From cce6a90a1503cf117080172493703680287bebd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Mon, 6 Apr 2020 14:56:20 +0200 Subject: [PATCH 01/31] ts-lint fixes --- client/src/components/context.vue | 32 +++++++++++++++---------------- client/src/locale/en-us.ts | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/client/src/components/context.vue b/client/src/components/context.vue index 11cf348f..34e82301 100644 --- a/client/src/components/context.vue +++ b/client/src/components/context.vue @@ -165,12 +165,12 @@ kick(member: Member) { this.$swal({ - title: this.$t('context.confirm.kick_title', { name: member.displayname }), - text: this.$t('context.confirm.kick_text', { name: member.displayname }), + title: this.$t('context.confirm.kick_title', { name: member.displayname }) as string, + text: this.$t('context.confirm.kick_text', { name: member.displayname }) as string, icon: 'warning', showCancelButton: true, - confirmButtonText: this.$t('context.confirm.button_yes'), - cancelButtonText: this.$t('context.confirm.button_cancel'), + confirmButtonText: this.$t('context.confirm.button_yes') as string, + cancelButtonText: this.$t('context.confirm.button_cancel') as string, }).then(({ value }) => { if (value) { this.$accessor.user.kick(member) @@ -180,12 +180,12 @@ ban(member: Member) { this.$swal({ - title: this.$t('context.confirm.ban_title', { name: member.displayname }), - text: this.$t('context.confirm.ban_text', { name: member.displayname }), + title: this.$t('context.confirm.ban_title', { name: member.displayname }) as string, + text: this.$t('context.confirm.ban_text', { name: member.displayname }) as string, icon: 'warning', showCancelButton: true, - confirmButtonText: this.$t('context.confirm.button_yes'), - cancelButtonText: this.$t('context.confirm.button_cancel'), + confirmButtonText: this.$t('context.confirm.button_yes') as string, + cancelButtonText: this.$t('context.confirm.button_cancel') as string, }).then(({ value }) => { if (value) { this.$accessor.user.ban(member) @@ -195,12 +195,12 @@ mute(member: Member) { this.$swal({ - title: this.$t('context.confirm.mute_title', { name: member.displayname }), - text: this.$t('context.confirm.mute_text', { name: member.displayname }), + title: this.$t('context.confirm.mute_title', { name: member.displayname }) as string, + text: this.$t('context.confirm.mute_text', { name: member.displayname }) as string, icon: 'warning', showCancelButton: true, - confirmButtonText: this.$t('context.confirm.button_yes'), - cancelButtonText: this.$t('context.confirm.button_cancel'), + confirmButtonText: this.$t('context.confirm.button_yes') as string, + cancelButtonText: this.$t('context.confirm.button_cancel') as string, }).then(({ value }) => { if (value) { this.$accessor.user.mute(member) @@ -210,12 +210,12 @@ unmute(member: Member) { this.$swal({ - title: this.$t('context.confirm.unmute_title', { name: member.displayname }), - text: this.$t('context.confirm.unmute_text', { name: member.displayname }), + title: this.$t('context.confirm.unmute_title', { name: member.displayname }) as string, + text: this.$t('context.confirm.unmute_text', { name: member.displayname }) as string, icon: 'warning', showCancelButton: true, - confirmButtonText: this.$t('context.confirm.button_yes'), - cancelButtonText: this.$t('context.confirm.button_cancel'), + confirmButtonText: this.$t('context.confirm.button_yes') as string, + cancelButtonText: this.$t('context.confirm.button_cancel') as string, }).then(({ value }) => { if (value) { this.$accessor.user.unmute(member) diff --git a/client/src/locale/en-us.ts b/client/src/locale/en-us.ts index 895ac208..62ff7df7 100644 --- a/client/src/locale/en-us.ts +++ b/client/src/locale/en-us.ts @@ -37,7 +37,7 @@ export const context = { unmute_text: 'Are you sure you want to unmute {name}?', button_yes: 'Yes', button_cancel: 'Cancel', - } + }, } export const controls = { From 85f2f41176025cb23c8206593486fd206f82a580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Mon, 6 Apr 2020 15:29:53 +0200 Subject: [PATCH 02/31] i18n improved --- client/src/components/side.vue | 4 ++-- client/src/locale/en-us.ts | 18 +++++++++++------- client/src/neko/index.ts | 18 +++++++++--------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/client/src/components/side.vue b/client/src/components/side.vue index 033ac07e..db1ff814 100644 --- a/client/src/components/side.vue +++ b/client/src/components/side.vue @@ -4,11 +4,11 @@ diff --git a/client/src/locale/en-us.ts b/client/src/locale/en-us.ts index 62ff7df7..1dfe6454 100644 --- a/client/src/locale/en-us.ts +++ b/client/src/locale/en-us.ts @@ -1,13 +1,13 @@ -export const chat = 'Chat' -export const settings = 'Settings' export const logout = 'logout' export const unsupported = 'this browser does not support webrtc' export const admin_loggedin = 'You are logged in as an admin' export const you = 'You' -export const ok = 'ok' export const send_a_message = 'Send a message' -export const connected = 'connected' -export const disconnected = 'disconnected' + +export const side = { + chat: 'Chat', + settings: 'Settings', +} export const connect = { title: 'Please Login', @@ -63,11 +63,15 @@ export const setting = { } export const connection = { - success: 'Successfully connected', + logged_out: 'You have been logged out!', + connected: 'Successfully connected', + disconnected: 'You have been disconnected', + button_confirm: 'Ok', } export const notifications = { - logged_out: '{name} logged out!', + connected: '{name} connected', + disconnected: '{name} disconnected', controls_taken: '{name} took the controls', controls_taken_force: 'force took the controls', controls_taken_steal: 'took the controls from {name}', diff --git a/client/src/neko/index.ts b/client/src/neko/index.ts index f2fca887..1db8fdd3 100644 --- a/client/src/neko/index.ts +++ b/client/src/neko/index.ts @@ -54,9 +54,9 @@ export class NekoClient extends BaseClient implements EventEmitter { this.disconnect() this.cleanup() this.$vue.$swal({ - title: this.$vue.$t('notifications.logged_out', { name: this.$vue.$t('you') }), + title: this.$vue.$t('connection.logged_out', { name: this.$vue.$t('you') }), icon: 'info', - confirmButtonText: this.$vue.$t('ok') as string, + confirmButtonText: this.$vue.$t('connection.button_confirm') as string, }) } @@ -75,7 +75,7 @@ export class NekoClient extends BaseClient implements EventEmitter { this.$vue.$notify({ group: 'neko', type: 'success', - title: this.$vue.$t('connection.success') as string, + title: this.$vue.$t('connection.connected') as string, duration: 5000, speed: 1000, }) @@ -86,7 +86,7 @@ export class NekoClient extends BaseClient implements EventEmitter { this.$vue.$notify({ group: 'neko', type: 'error', - title: this.$vue.$t('disconnected') as string, + title: this.$vue.$t('connection.disconnected') as string, text: reason ? reason.message : undefined, duration: 5000, speed: 1000, @@ -111,10 +111,10 @@ export class NekoClient extends BaseClient implements EventEmitter { protected [EVENT.SYSTEM.DISCONNECT]({ message }: DisconnectPayload) { this.onDisconnected(new Error(message)) this.$vue.$swal({ - title: this.$vue.$t('disconnected'), + title: this.$vue.$t('connection.disconnected'), text: message, icon: 'error', - confirmButtonText: this.$vue.$t('ok') as string, + confirmButtonText: this.$vue.$t('connection.button_confirm') as string, }) } @@ -125,7 +125,7 @@ export class NekoClient extends BaseClient implements EventEmitter { this.$accessor.user.setMembers(members) this.$accessor.chat.newMessage({ id: this.id, - content: this.$vue.$t('connected') as string, + content: this.$vue.$t('notifications.connected', { name: '' }) as string, type: 'event', created: new Date(), }) @@ -137,7 +137,7 @@ export class NekoClient extends BaseClient implements EventEmitter { if (member.id !== this.id) { this.$accessor.chat.newMessage({ id: member.id, - content: this.$vue.$t('connected') as string, + content: this.$vue.$t('notifications.connected', { name: '' }) as string, type: 'event', created: new Date(), }) @@ -152,7 +152,7 @@ export class NekoClient extends BaseClient implements EventEmitter { this.$accessor.chat.newMessage({ id: member.id, - content: this.$vue.$t('disconnected') as string, + content: this.$vue.$t('notifications.disconnected', { name: '' }) as string, type: 'event', created: new Date(), }) From 2fa5839b9982681eb4921cedcf735cb787710641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Mon, 6 Apr 2020 15:32:06 +0200 Subject: [PATCH 03/31] connection.logged_out does not have 'you' anymore --- client/src/neko/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/neko/index.ts b/client/src/neko/index.ts index 1db8fdd3..880e7935 100644 --- a/client/src/neko/index.ts +++ b/client/src/neko/index.ts @@ -54,7 +54,7 @@ export class NekoClient extends BaseClient implements EventEmitter { this.disconnect() this.cleanup() this.$vue.$swal({ - title: this.$vue.$t('connection.logged_out', { name: this.$vue.$t('you') }), + title: this.$vue.$t('connection.logged_out'), icon: 'info', confirmButtonText: this.$vue.$t('connection.button_confirm') as string, }) From 080766481c49f9711e35af1374df7707aea9beb6 Mon Sep 17 00:00:00 2001 From: Ellen Marie Dash Date: Mon, 6 Apr 2020 13:09:32 -0400 Subject: [PATCH 04/31] Fix _+: keys in Firefox 19466b5 fixes the keys without shift; this fixes them with shift. Related: https://github.com/nurdism/neko/commit/19466b5625b6e6c2796faa7eeac0e3be1797f7f5 Context: https://github.com/nurdism/neko/issues/51#issuecomment-609877197 --- client/src/components/video.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/components/video.vue b/client/src/components/video.vue index 00dd11b7..b56add24 100644 --- a/client/src/components/video.vue +++ b/client/src/components/video.vue @@ -466,15 +466,15 @@ // frick you firefox getCode(e: KeyboardEvent): number { let key = e.keyCode - if (key === 59 && e.key === ';') { + if (key === 59 && (e.key === ';' || e.key === ':')) { key = 186 } - if (key === 61 && e.key === '=') { + if (key === 61 && (e.key === '=' || e.key === '+')) { key = 187 } - if (key === 173 && e.key === '-') { + if (key === 173 && (e.key === '-' || e.key === '_')) { key = 189 } From 414b5a80151a697402d7c62e1cb5f779e601c01e Mon Sep 17 00:00:00 2001 From: Craig Date: Mon, 6 Apr 2020 20:14:08 +0000 Subject: [PATCH 05/31] unlock room if no admins online --- server/internal/session/manager.go | 21 ++++++++++++++++++--- server/internal/types/session.go | 3 ++- server/internal/websocket/handler.go | 4 ++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/server/internal/session/manager.go b/server/internal/session/manager.go index 15b2d4f1..8e51bc5a 100644 --- a/server/internal/session/manager.go +++ b/server/internal/session/manager.go @@ -88,6 +88,21 @@ func (manager *SessionManager) Get(id string) (types.Session, bool) { return session, ok } +func (manager *SessionManager) Admins() []*types.Member { + members := []*types.Member{} + for _, session := range manager.members { + if !session.connected || !session.admin { + continue + } + + member := session.Member() + if member != nil { + members = append(members, member) + } + } + return members +} + func (manager *SessionManager) Members() []*types.Member { members := []*types.Member{} for _, session := range manager.members { @@ -113,7 +128,7 @@ func (manager *SessionManager) Destroy(id string) error { manager.remote.StopStream() } - manager.emmiter.Emit("destroyed", id) + manager.emmiter.Emit("destroyed", id, session) return err } @@ -155,9 +170,9 @@ func (manager *SessionManager) OnHostCleared(listener func(id string)) { }) } -func (manager *SessionManager) OnDestroy(listener func(id string)) { +func (manager *SessionManager) OnDestroy(listener func(id string, session types.Session)) { manager.emmiter.On("destroyed", func(payload ...interface{}) { - listener(payload[0].(string)) + listener(payload[0].(string), payload[1].(*Session)) }) } diff --git a/server/internal/types/session.go b/server/internal/types/session.go index 1c8acabd..acdcac64 100644 --- a/server/internal/types/session.go +++ b/server/internal/types/session.go @@ -36,12 +36,13 @@ type SessionManager interface { Has(id string) bool Get(id string) (Session, bool) Members() []*Member + Admins() []*Member Destroy(id string) error Clear() error Broadcast(v interface{}, exclude interface{}) error OnHost(listener func(id string)) OnHostCleared(listener func(id string)) - OnDestroy(listener func(id string)) + OnDestroy(listener func(id string, session Session)) OnCreated(listener func(id string, session Session)) OnConnected(listener func(id string, session Session)) } diff --git a/server/internal/websocket/handler.go b/server/internal/websocket/handler.go index e350752d..fddd63fa 100644 --- a/server/internal/websocket/handler.go +++ b/server/internal/websocket/handler.go @@ -42,6 +42,10 @@ func (h *MessageHandler) Connected(id string, socket *WebSocket) (bool, string, } func (h *MessageHandler) Disconnected(id string) error { + if h.locked && len(h.sessions.Admins()) == 0 { + h.locked = false + } + return h.sessions.Destroy(id) } From 584513de9b2b883a2a759ec88f432a0325000664 Mon Sep 17 00:00:00 2001 From: Craig Date: Mon, 6 Apr 2020 20:14:30 +0000 Subject: [PATCH 06/31] reverse proxy mode --- server/internal/types/config/websocket.go | 7 +++++++ server/internal/websocket/websocket.go | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/server/internal/types/config/websocket.go b/server/internal/types/config/websocket.go index b93dc594..099f34bd 100644 --- a/server/internal/types/config/websocket.go +++ b/server/internal/types/config/websocket.go @@ -8,6 +8,7 @@ import ( type WebSocket struct { Password string AdminPassword string + Proxy bool } func (WebSocket) Init(cmd *cobra.Command) error { @@ -21,10 +22,16 @@ func (WebSocket) Init(cmd *cobra.Command) error { return err } + cmd.PersistentFlags().Bool("proxy", false, "enable reverse proxy mode") + if err := viper.BindPFlag("proxy", cmd.PersistentFlags().Lookup("proxy")); err != nil { + return err + } + return nil } func (s *WebSocket) Set() { s.Password = viper.GetString("password") s.AdminPassword = viper.GetString("password_admin") + s.Proxy = viper.GetBool("proxy") } diff --git a/server/internal/websocket/websocket.go b/server/internal/websocket/websocket.go index 1fe45986..fc6b4e35 100644 --- a/server/internal/websocket/websocket.go +++ b/server/internal/websocket/websocket.go @@ -70,7 +70,7 @@ func (ws *WebSocketHandler) Start() error { } }) - ws.sessions.OnDestroy(func(id string) { + ws.sessions.OnDestroy(func(id string, session types.Session) { if err := ws.handler.SessionDestroyed(id); err != nil { ws.logger.Warn().Str("id", id).Err(err).Msg("session destroyed with and error") } else { @@ -191,7 +191,11 @@ func (ws *WebSocketHandler) Upgrade(w http.ResponseWriter, r *http.Request) erro } func (ws *WebSocketHandler) authenticate(r *http.Request) (string, string, bool, error) { - ip := utils.ReadUserIP(r) + ip := r.RemoteAddr + + if ws.conf.Proxy { + ip = utils.ReadUserIP(r) + } id, err := utils.NewUID(32) if err != nil { From 470bb2f659f49301aa84b0451b432347dfe621d3 Mon Sep 17 00:00:00 2001 From: Craig Date: Mon, 6 Apr 2020 20:14:50 +0000 Subject: [PATCH 07/31] type error --- server/internal/types/config/broadcast.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/internal/types/config/broadcast.go b/server/internal/types/config/broadcast.go index f31888a3..35c35024 100644 --- a/server/internal/types/config/broadcast.go +++ b/server/internal/types/config/broadcast.go @@ -6,7 +6,7 @@ import ( ) type Broadcast struct { - Enabled string + Enabled bool Display string Device string AudioParams string From 8cea01f1645995a13efae6e616baf0396f069256 Mon Sep 17 00:00:00 2001 From: Craig Date: Mon, 6 Apr 2020 20:15:32 +0000 Subject: [PATCH 08/31] fix CreatePipeline func --- server/internal/gst/gst.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/internal/gst/gst.go b/server/internal/gst/gst.go index 80c07979..1c0eb90d 100644 --- a/server/internal/gst/gst.go +++ b/server/internal/gst/gst.go @@ -68,7 +68,7 @@ func init() { func CreateRTMPPipeline(pipelineDevice string, pipelineDisplay string, pipelineRTMP string) (*Pipeline, error) { video := fmt.Sprintf(videoSrc, pipelineDisplay) audio := fmt.Sprintf(audioSrc, pipelineDevice) - return CreatePipeline(fmt.Sprintf("%s ! x264enc ! flv. ! %s ! faac ! flv. ! flvmux name='flv' ! rtmpsink location='%s'", video, audio, pipelineRTMP)) + return CreatePipeline(fmt.Sprintf("%s ! x264enc ! flv. ! %s ! faac ! flv. ! flvmux name='flv' ! rtmpsink location='%s'", video, audio, pipelineRTMP), "", 0) } // CreateAppPipeline creates a GStreamer Pipeline @@ -199,11 +199,11 @@ func CreateAppPipeline(codecName string, pipelineDevice string, pipelineSrc stri return nil, fmt.Errorf("unknown codec %s", codecName) } - return CreatePipeline(pipelineStr) + return CreatePipeline(pipelineStr, codecName, clockRate) } // CreatePipeline creates a GStreamer Pipeline -func CreatePipeline(pipelineStr string) (*Pipeline, error) { +func CreatePipeline(pipelineStr string, codecName string, clockRate float32) (*Pipeline, error) { pipelineStrUnsafe := C.CString(pipelineStr) defer C.free(unsafe.Pointer(pipelineStrUnsafe)) From 1e77a1afde8a8fc4f6b874f953eb1b008bd030b5 Mon Sep 17 00:00:00 2001 From: Craig Date: Mon, 6 Apr 2020 20:22:17 +0000 Subject: [PATCH 09/31] hide kicak/ban from context if admin --- client/src/components/context.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/context.vue b/client/src/components/context.vue index 34e82301..db2de331 100644 --- a/client/src/components/context.vue +++ b/client/src/components/context.vue @@ -36,7 +36,7 @@ -