Преглед на файлове

feat(recording): Shows notification when you try to start recording too quick. (#15311)

* feat(recording): Shows notification when you try to start recording too quick.

* squash: separate values ip and room.

* chore(deps) lib-jitsi-meet@latest

https://github.com/jitsi/lib-jitsi-meet/compare/v1886.0.0+bc446e99...v1887.0.0+9652999d

* squash: text adjust
factor2
Дамян Минков преди 7 месеца
родител
ревизия
50e9413aad
No account linked to committer's email address

+ 2
- 0
lang/main.json Целия файл

@@ -641,6 +641,7 @@
641 641
         "on": "Live Streaming started",
642 642
         "onBy": "{{name}} started the live streaming",
643 643
         "pending": "Starting Live Stream…",
644
+        "policyError": "You tried to start a live stream too quickly. Please try again later!",
644 645
         "serviceName": "Live Streaming service",
645 646
         "sessionAlreadyActive": "This session is already being recorded or live streamed.",
646 647
         "signIn": "Sign in with Google",
@@ -1055,6 +1056,7 @@
1055 1056
         "onBy": "{{name}} started the recording",
1056 1057
         "onlyRecordSelf": "Record only my audio and video streams",
1057 1058
         "pending": "Preparing to record the meeting…",
1059
+        "policyError": "You tried to start a recording too quickly. Please try again later!",
1058 1060
         "recordAudioAndVideo": "Record audio and video",
1059 1061
         "recordTranscription": "Record transcription",
1060 1062
         "saveLocalRecording": "Save recording file locally (Beta)",

+ 5
- 5
package-lock.json Целия файл

@@ -62,7 +62,7 @@
62 62
         "js-md5": "0.6.1",
63 63
         "js-sha512": "0.8.0",
64 64
         "jwt-decode": "2.2.0",
65
-        "lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1886.0.0+bc446e99/lib-jitsi-meet.tgz",
65
+        "lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1887.0.0+9652999d/lib-jitsi-meet.tgz",
66 66
         "lodash-es": "4.17.21",
67 67
         "moment": "2.29.4",
68 68
         "moment-duration-format": "2.2.2",
@@ -15970,8 +15970,8 @@
15970 15970
     },
15971 15971
     "node_modules/lib-jitsi-meet": {
15972 15972
       "version": "0.0.0",
15973
-      "resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1886.0.0+bc446e99/lib-jitsi-meet.tgz",
15974
-      "integrity": "sha512-/XTGm2r3cgKZBMyPS5LHaX9DCZVpY6omWSnh7xkwYtSQtJXIbSKI07Mgmah6o0p8Y3/XsC7xUMfS0qOKn8TlYQ==",
15973
+      "resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1887.0.0+9652999d/lib-jitsi-meet.tgz",
15974
+      "integrity": "sha512-WQ4sF0B+K0V+nqTr8ldFuQkvNxp+2DTUIu+ix0cE6L+NsS1yorRus/mG5lMlaQU9So0W83fnsl38kIj1RuymRQ==",
15975 15975
       "hasInstallScript": true,
15976 15976
       "license": "Apache-2.0",
15977 15977
       "dependencies": {
@@ -35316,8 +35316,8 @@
35316 35316
       }
35317 35317
     },
35318 35318
     "lib-jitsi-meet": {
35319
-      "version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1886.0.0+bc446e99/lib-jitsi-meet.tgz",
35320
-      "integrity": "sha512-/XTGm2r3cgKZBMyPS5LHaX9DCZVpY6omWSnh7xkwYtSQtJXIbSKI07Mgmah6o0p8Y3/XsC7xUMfS0qOKn8TlYQ==",
35319
+      "version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1887.0.0+9652999d/lib-jitsi-meet.tgz",
35320
+      "integrity": "sha512-WQ4sF0B+K0V+nqTr8ldFuQkvNxp+2DTUIu+ix0cE6L+NsS1yorRus/mG5lMlaQU9So0W83fnsl38kIj1RuymRQ==",
35321 35321
       "requires": {
35322 35322
         "@jitsi/js-utils": "2.2.1",
35323 35323
         "@jitsi/logger": "2.0.2",

+ 1
- 1
package.json Целия файл

@@ -68,7 +68,7 @@
68 68
     "js-md5": "0.6.1",
69 69
     "js-sha512": "0.8.0",
70 70
     "jwt-decode": "2.2.0",
71
-    "lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1886.0.0+bc446e99/lib-jitsi-meet.tgz",
71
+    "lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1887.0.0+9652999d/lib-jitsi-meet.tgz",
72 72
     "lodash-es": "4.17.21",
73 73
     "moment": "2.29.4",
74 74
     "moment-duration-format": "2.2.2",

+ 6
- 0
react/features/recording/middleware.ts Целия файл

@@ -364,6 +364,12 @@ function _showRecordingErrorNotification(session: any, dispatch: IStore['dispatc
364 364
             titleKey: isStreamMode ? 'liveStreaming.inProgress' : 'recording.inProgress'
365 365
         }));
366 366
         break;
367
+    case JitsiMeetJS.constants.recording.error.POLICY_VIOLATION:
368
+        dispatch(showRecordingWarning({
369
+            descriptionKey: isStreamMode ? 'liveStreaming.policyError' : 'recording.policyError',
370
+            titleKey: isStreamMode ? 'liveStreaming.failedToStart' : 'recording.failedToStart'
371
+        }));
372
+        break;
367 373
     default:
368 374
         dispatch(showRecordingError({
369 375
             descriptionKey: isStreamMode

+ 39
- 4
resources/prosody-plugins/mod_filter_iq_jibri.lua Целия файл

@@ -1,11 +1,28 @@
1 1
 -- This module is enabled under the main virtual host
2
+local cache = require 'util.cache';
3
+local new_throttle = require 'util.throttle'.create;
2 4
 local st = require "util.stanza";
3 5
 local jid_bare = require "util.jid".bare;
4 6
 local util = module:require 'util';
5 7
 local is_feature_allowed = util.is_feature_allowed;
8
+local get_ip = util.get_ip;
6 9
 local get_room_from_jid = util.get_room_from_jid;
7 10
 local room_jid_match_rewrite = util.room_jid_match_rewrite;
8 11
 
12
+local limit_jibri_reach_ip_attempts;
13
+local limit_jibri_reach_room_attempts;
14
+local rates_per_ip;
15
+local function load_config()
16
+    limit_jibri_reach_ip_attempts = module:get_option_number("max_number_ip_attempts_per_minute", 9);
17
+    limit_jibri_reach_room_attempts = module:get_option_number("max_number_room_attempts_per_minute", 3);
18
+    -- The size of the cache that saves state for IP addresses
19
+    cache_size = module:get_option_number("jibri_rate_limit_cache_size", 10000);
20
+
21
+    -- Maps an IP address to a util.throttle which keeps the rate of attempts to reach jibri events from that IP.
22
+    rates_per_ip = cache.new(cache_size);
23
+end
24
+load_config();
25
+
9 26
 -- filters jibri iq in case of requested from jwt authenticated session that
10 27
 -- has features in the user context, but without feature for recording
11 28
 module:hook("pre-iq/full", function(event)
@@ -24,10 +41,28 @@ module:hook("pre-iq/full", function(event)
24 41
                 session.granted_jitsi_meet_context_features,
25 42
                 occupant.role == 'moderator');
26 43
 
27
-            if jibri.attr.action == 'start' and not is_allowed then
28
-                module:log('info', 'Filtering jibri start recording, stanza:%s', tostring(stanza));
29
-                session.send(st.error_reply(stanza, 'auth', 'forbidden'));
30
-                return true;
44
+            if jibri.attr.action == 'start' then
45
+                if not is_allowed then
46
+                    module:log('info', 'Filtering jibri start recording, stanza:%s', tostring(stanza));
47
+                    session.send(st.error_reply(stanza, 'auth', 'forbidden'));
48
+                    return true;
49
+                end
50
+
51
+                local ip = get_ip(session);
52
+                if not rates_per_ip:get(ip) then
53
+                    rates_per_ip:set(ip, new_throttle(limit_jibri_reach_ip_attempts, 60));
54
+                end
55
+
56
+                if not room.jibri_throttle then
57
+                    room.jibri_throttle = new_throttle(limit_jibri_reach_room_attempts, 60);
58
+                end
59
+
60
+                if not rates_per_ip:get(ip):poll(1) or not room.jibri_throttle:poll(1) then
61
+                    module:log('warn', 'Filtering jibri start recording, ip:%s, room:%s stanza:%s',
62
+                        ip, room.jid, tostring(stanza));
63
+                    session.send(st.error_reply(stanza, 'wait', 'policy-violation'));
64
+                    return true;
65
+                end
31 66
             end
32 67
         end
33 68
     end

+ 3
- 8
resources/prosody-plugins/mod_rate_limit.lua Целия файл

@@ -14,6 +14,7 @@ local ip_util = require "util.ip";
14 14
 local new_ip = ip_util.new_ip;
15 15
 local match_ip = ip_util.match;
16 16
 local parse_cidr = ip_util.parse_cidr;
17
+local get_ip = module:require "util".get_ip;
17 18
 
18 19
 local config = {};
19 20
 local limits_resolution = 1;
@@ -76,14 +77,6 @@ local function is_whitelisted_host(h)
76 77
 	return config.whitelist_hosts:contains(h);
77 78
 end
78 79
 
79
-local get_request_from_conn = http_server.get_request_from_conn or function (conn)
80
-	local response = conn and conn._http_open_response;
81
-	return response and response.request or nil;
82
-end;
83
-
84 80
 -- Add an IP to the set of limied IPs
85 81
 local function limit_ip(ip)
86 82
 	module:log("info", "Limiting %s due to login/join rate exceeded.", ip);
@@ -192,9 +185,8 @@ local function filter_hook(session)
192 185
         return;
193 186
     end
194 187
 
195
-	local request = get_request_from_conn(session.conn);
196
-	local ip = request and request.ip or session.ip;
197
-	module:log("debug", "New session from %s", ip);
188
+    local ip = get_ip(session);
189
+    module:log("debug", "New session from %s", ip);
198 190
     if is_whitelisted(ip) or is_whitelisted_host(session.host) then
199 191
         return;
200 192
     end

+ 15
- 0
resources/prosody-plugins/util.lib.lua Целия файл

@@ -1,3 +1,4 @@
1
+local http_server = require "net.http.server";
1 2
 local jid = require "util.jid";
2 3
 local st = require 'util.stanza';
3 4
 local timer = require "util.timer";
@@ -578,6 +579,19 @@ function respond_iq_result(origin, stanza)
578 579
     }));
579 580
 end
580 581
 
582
+-- Note: http_server.get_request_from_conn() was added in Prosody 0.12.3,
583
+-- this code provides backwards compatibility with older versions
584
+local get_request_from_conn = http_server.get_request_from_conn or function (conn)
585
+    local response = conn and conn._http_open_response;
586
+    return response and response.request or nil;
587
+end;
588
+
589
+-- Discover real remote IP of a session
590
+function get_ip(session)
591
+    local request = get_request_from_conn(session.conn);
592
+    return request and request.ip or session.ip;
593
+end
594
+
581 595
 return {
582 596
     OUTBOUND_SIP_JIBRI_PREFIXES = OUTBOUND_SIP_JIBRI_PREFIXES;
583 597
     INBOUND_SIP_JIBRI_PREFIXES = INBOUND_SIP_JIBRI_PREFIXES;
@@ -590,6 +604,7 @@ return {
590 604
     is_transcriber_jigasi = is_transcriber_jigasi;
591 605
     is_vpaas = is_vpaas;
592 606
     get_focus_occupant = get_focus_occupant;
607
+    get_ip = get_ip;
593 608
     get_room_from_jid = get_room_from_jid;
594 609
     get_room_by_name_and_subdomain = get_room_by_name_and_subdomain;
595 610
     get_sip_jibri_email_prefix = get_sip_jibri_email_prefix;

Loading…
Отказ
Запис