diff --git a/SECURITY.md b/SECURITY.md index 7b3d63613a..ad2643345b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -17,7 +17,7 @@ As such, we recommend that all administrators deploy 2.7 going forward. You'll ## Reporting a Vulnerability -If you believe you have found a security vunerability in BigBlueButton please let us know directly by +If you believe you have found a security vulnerability in BigBlueButton please let us know directly by - using GitHub's "Report a vulnerability" functionality on https://github.com/bigbluebutton/bigbluebutton/security/advisories - or e-mailing security@bigbluebutton.org with as much detail as possible. diff --git a/akka-bbb-apps/project/Dependencies.scala b/akka-bbb-apps/project/Dependencies.scala index ce742630e5..d9ac0a8e1c 100755 --- a/akka-bbb-apps/project/Dependencies.scala +++ b/akka-bbb-apps/project/Dependencies.scala @@ -16,7 +16,7 @@ object Dependencies { val pekkoHttpVersion = "1.0.0" val gson = "2.8.9" val jackson = "2.13.5" - val logback = "1.2.11" + val logback = "1.2.13" val quicklens = "1.7.5" val spray = "1.3.6" diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala index cdab3d7cb8..9a32f958da 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/SystemConfiguration.scala @@ -13,6 +13,7 @@ trait SystemConfiguration { lazy val bbbWebPort = Try(config.getInt("services.bbbWebPort")).getOrElse(8888) lazy val bbbWebAPI = Try(config.getString("services.bbbWebAPI")).getOrElse("localhost") lazy val bbbWebSharedSecret = Try(config.getString("services.sharedSecret")).getOrElse("changeme") + lazy val checkSumAlgorithmForBreakouts = Try(config.getString("services.checkSumAlgorithmForBreakouts")).getOrElse("sha256") lazy val bbbWebModeratorPassword = Try(config.getString("services.moderatorPassword")).getOrElse("changeme") lazy val bbbWebViewerPassword = Try(config.getString("services.viewerPassword")).getOrElse("changeme") lazy val keysExpiresInSec = Try(config.getInt("redis.keyExpiry")).getOrElse(14 * 86400) // 14 days diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutApp2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutApp2x.scala index a780ecdb56..9a02c67527 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutApp2x.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/breakout/BreakoutApp2x.scala @@ -4,6 +4,7 @@ import org.bigbluebutton.core.running.MeetingActor import java.net.URLEncoder import scala.collection.SortedSet import org.apache.commons.codec.digest.DigestUtils +import org.bigbluebutton.SystemConfiguration trait BreakoutApp2x extends BreakoutRoomCreatedMsgHdlr with BreakoutRoomsListMsgHdlr @@ -26,7 +27,7 @@ trait BreakoutApp2x extends BreakoutRoomCreatedMsgHdlr } -object BreakoutRoomsUtil { +object BreakoutRoomsUtil extends SystemConfiguration { def createMeetingIds(id: String, index: Int): (String, String) = { val timeStamp = System.currentTimeMillis() val externalHash = DigestUtils.sha1Hex(id.concat("-").concat(timeStamp.toString()).concat("-").concat(index.toString())) @@ -48,7 +49,13 @@ object BreakoutRoomsUtil { //checksum() -- Return a checksum based on SHA-1 digest // def checksum(s: String): String = { - DigestUtils.sha256Hex(s); + checkSumAlgorithmForBreakouts match { + case "sha1" => DigestUtils.sha1Hex(s); + case "sha256" => DigestUtils.sha256Hex(s); + case "sha384" => DigestUtils.sha384Hex(s); + case "sha512" => DigestUtils.sha512Hex(s); + case _ => DigestUtils.sha256Hex(s); // default + } } def calculateChecksum(apiCall: String, baseString: String, sharedSecret: String): String = { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPresenterInDefaultPodInternalMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPresenterInDefaultPodInternalMsgHdlr.scala index 0ef30661a0..b1bf9200b2 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPresenterInDefaultPodInternalMsgHdlr.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentationpod/SetPresenterInDefaultPodInternalMsgHdlr.scala @@ -15,7 +15,7 @@ trait SetPresenterInDefaultPodInternalMsgHdlr { msg: SetPresenterInDefaultPodInternalMsg, state: MeetingState2x, liveMeeting: LiveMeeting, bus: MessageBus ): MeetingState2x = { - // Swith presenter as default presenter pod has changed. + // Switch presenter as default presenter pod has changed. log.info("Presenter pod change will trigger a presenter change") SetPresenterInPodActionHandler.handleAction(state, liveMeeting, bus.outGW, "", PresentationPod.DEFAULT_PRESENTATION_POD, msg.presenterId) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/jhotdraw/Bezier.java b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/jhotdraw/Bezier.java index 1afba2976d..0f7fe3803c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/jhotdraw/Bezier.java +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/jhotdraw/Bezier.java @@ -367,7 +367,7 @@ public class Bezier { * @param first Indice of first point in d. * @param last Indice of last point in d. * @param tHat1 Unit tangent vectors at start point. - * @param tHat2 Unit tanget vector at end point. + * @param tHat2 Unit tangent vector at end point. * @param errorSquared User-defined errorSquared squared. * @param bezierPath Path to which the bezier curve segments are added. */ @@ -580,7 +580,7 @@ public class Bezier { * * @param Q Current fitted bezier curve. * @param P Digitized point. - * @param u Parameter value vor P. + * @param u Parameter value for P. */ private static double newtonRaphsonRootFind(Point2D.Double[] Q, Point2D.Double P, double u) { double numerator, denominator; @@ -661,7 +661,7 @@ public class Bezier { * @param last Indice of last point in d. * @param uPrime Parameter values for region . * @param tHat1 Unit tangent vectors at start point. - * @param tHat2 Unit tanget vector at end point. + * @param tHat2 Unit tangent vector at end point. * @return A cubic bezier curve consisting of 4 control points. */ private static Point2D.Double[] generateBezier(ArrayList d, int first, int last, double[] uPrime, Point2D.Double tHat1, Point2D.Double tHat2) { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/jhotdraw/BezierPath.java b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/jhotdraw/BezierPath.java index c2a7981e52..11b860de75 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/jhotdraw/BezierPath.java +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/util/jhotdraw/BezierPath.java @@ -40,7 +40,7 @@ public class BezierPath extends ArrayList private static final long serialVersionUID=1L; /** Constant for having only control point C0 in effect. C0 is the point - * through whitch the curve passes. */ + * through which the curve passes. */ public static final int C0_MASK = 0; /** Constant for having control point C1 in effect (in addition * to C0). C1 controls the curve going towards C0. diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala index 594cb95c2b..e5ba2c73dd 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala @@ -115,7 +115,7 @@ class RedisRecorderActor( //case m: DeskShareNotifyViewersRTMP => handleDeskShareNotifyViewersRTMP(m) // AudioCaptions - case m: TranscriptUpdatedEvtMsg => handleTranscriptUpdatedEvtMsg(m) + //case m: TranscriptUpdatedEvtMsg => handleTranscriptUpdatedEvtMsg(m) // temporarily disabling due to issue https://github.com/bigbluebutton/bigbluebutton/issues/19701 // Meeting case m: RecordingStatusChangedEvtMsg => handleRecordingStatusChangedEvtMsg(m) @@ -284,7 +284,7 @@ class RedisRecorderActor( } private def getPresentationId(whiteboardId: String): String = { - // Need to split the whiteboard id into presenation id and page num as the old + // Need to split the whiteboard id into presentation id and page num as the old // recording expects them val strId = new StringOps(whiteboardId) val ids = strId.split('/') @@ -536,6 +536,7 @@ class RedisRecorderActor( } */ + /* temporarily disabling due to issue https://github.com/bigbluebutton/bigbluebutton/issues/19701 private def handleTranscriptUpdatedEvtMsg(msg: TranscriptUpdatedEvtMsg) { val ev = new TranscriptUpdatedRecordEvent() ev.setMeetingId(msg.header.meetingId) @@ -544,6 +545,7 @@ class RedisRecorderActor( record(msg.header.meetingId, ev.toMap.asJava) } + */ private def handleStartExternalVideoEvtMsg(msg: StartExternalVideoEvtMsg) { val ev = new StartExternalVideoRecordEvent() diff --git a/akka-bbb-apps/src/universal/conf/application.conf b/akka-bbb-apps/src/universal/conf/application.conf index e703d8c9c1..57936377e2 100755 --- a/akka-bbb-apps/src/universal/conf/application.conf +++ b/akka-bbb-apps/src/universal/conf/application.conf @@ -65,6 +65,7 @@ expire { services { bbbWebAPI = "https://192.168.23.33/bigbluebutton/api" sharedSecret = "changeme" + checkSumAlgorithmForBreakouts = "sha256" } eventBus { diff --git a/akka-bbb-fsesl/project/Dependencies.scala b/akka-bbb-fsesl/project/Dependencies.scala index 66941a8646..53b57c6ba6 100755 --- a/akka-bbb-fsesl/project/Dependencies.scala +++ b/akka-bbb-fsesl/project/Dependencies.scala @@ -14,7 +14,7 @@ object Dependencies { // Libraries val pekkoVersion = "1.0.1" val pekkoHttpVersion = "1.0.0" - val logback = "1.2.10" + val logback = "1.2.13" // Apache Commons val lang = "3.12.0" diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMsgs.scala index b1744b65d7..11a6b798ad 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/UsersMsgs.scala @@ -143,7 +143,7 @@ case class SetRecordingStatusCmdMsg(header: BbbClientMsgHeader, body: SetRecordi case class SetRecordingStatusCmdMsgBody(recording: Boolean, setBy: String) /** - * Sent by user to start recording mark and ignore previsous marks + * Sent by user to start recording mark and ignore previous marks */ object RecordAndClearPreviousMarkersCmdMsg { val NAME = "RecordAndClearPreviousMarkersCmdMsg" } case class RecordAndClearPreviousMarkersCmdMsg(header: BbbClientMsgHeader, body: RecordAndClearPreviousMarkersCmdMsgBody) extends StandardMsg diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java index 63e709764e..949dcf5be4 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/ApiParams.java @@ -111,7 +111,7 @@ public class ApiParams { public static final String RECORD_FULL_DURATION_MEDIA = "recordFullDurationMedia"; private ApiParams() { - throw new IllegalStateException("ApiParams is a utility class. Instanciation is forbidden."); + throw new IllegalStateException("ApiParams is a utility class. Instantiation is forbidden."); } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/service/impl/RecordingServiceFileImpl.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/service/impl/RecordingServiceFileImpl.java index 2e6e712656..611cdf3542 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/service/impl/RecordingServiceFileImpl.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/service/impl/RecordingServiceFileImpl.java @@ -124,7 +124,7 @@ public class RecordingServiceFileImpl implements RecordingService { if (!doneFile.exists()) log.error("Failed to create {} file.", done); } catch (IOException e) { - log.error("Exception occured when trying to create {} file", done); + log.error("Exception occurred when trying to create {} file", done); } } else { log.error("{} file already exists.", done); @@ -141,7 +141,7 @@ public class RecordingServiceFileImpl implements RecordingService { if (!doneFile.exists()) log.error("Failed to create {} file.", done); } catch (IOException e) { - log.error("Exception occured when trying to create {} file.", done); + log.error("Exception occurred when trying to create {} file.", done); } } else { log.error("{} file already exists.", done); @@ -158,7 +158,7 @@ public class RecordingServiceFileImpl implements RecordingService { if (!doneFile.exists()) log.error("Failed to create " + done + " file."); } catch (IOException e) { - log.error("Exception occured when trying to create {} file.", done); + log.error("Exception occurred when trying to create {} file.", done); } } else { log.error(done + " file already exists."); diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ResponseBuilder.java b/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ResponseBuilder.java index 3e052b02d1..e7a7a7a32c 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ResponseBuilder.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/api/util/ResponseBuilder.java @@ -37,7 +37,7 @@ public class ResponseBuilder { try { cfg.setDirectoryForTemplateLoading(templatesLoc); } catch (IOException e) { - log.error("Exception occured creating ResponseBuilder", e); + log.error("Exception occurred creating ResponseBuilder", e); } setUpConfiguration(); } @@ -97,12 +97,12 @@ public class ResponseBuilder { return xmlText.toString(); } - public String buildErrors(ArrayList erros, String returnCode) { + public String buildErrors(ArrayList errors, String returnCode) { StringWriter xmlText = new StringWriter(); Map data = new HashMap(); data.put("returnCode", returnCode); - data.put("errorsList", erros); + data.put("errorsList", errors); processData(getTemplate("api-errors.ftlx"), data, xmlText); diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/ConversionMessageConstants.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/ConversionMessageConstants.java index 57c3ac2c41..d79f4537b1 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/ConversionMessageConstants.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/ConversionMessageConstants.java @@ -41,6 +41,6 @@ public class ConversionMessageConstants { public static final String CONVERSION_TIMEOUT_KEY = "CONVERSION_TIMEOUT"; private ConversionMessageConstants() { - throw new IllegalStateException("ConversionMessageConstants is a utility class. Instanciation is forbidden."); + throw new IllegalStateException("ConversionMessageConstants is a utility class. Instantiation is forbidden."); } } diff --git a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/ExternalProcessExecutor.java b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/ExternalProcessExecutor.java index d583f1eaad..268109457e 100755 --- a/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/ExternalProcessExecutor.java +++ b/bbb-common-web/src/main/java/org/bigbluebutton/presentation/imp/ExternalProcessExecutor.java @@ -81,7 +81,7 @@ public class ExternalProcessExecutor { try { if (!proc.waitFor(timeout.toMillis(), TimeUnit.MILLISECONDS)) { - log.warn("TIMEDOUT excuting: {}", String.join(" ", cmd)); + log.warn("TIMEDOUT executing: {}", String.join(" ", cmd)); proc.destroy(); } return !proc.isAlive() && proc.exitValue() == 0; diff --git a/bbb-fsesl-client/project/Dependencies.scala b/bbb-fsesl-client/project/Dependencies.scala index 552b4e1a60..ba2d911dfe 100644 --- a/bbb-fsesl-client/project/Dependencies.scala +++ b/bbb-fsesl-client/project/Dependencies.scala @@ -11,7 +11,7 @@ object Dependencies { // Libraries val netty = "3.2.10.Final" - val logback = "1.2.10" + val logback = "1.2.13" // Test val junit = "4.12" diff --git a/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/inbound/Client.java b/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/inbound/Client.java index e09669031f..1e54a593be 100755 --- a/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/inbound/Client.java +++ b/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/inbound/Client.java @@ -157,7 +157,7 @@ public class Client * Sends a FreeSWITCH API command to the server and blocks, waiting for an immediate response from the * server. *

- * The outcome of the command from the server is retured in an {@link EslMessage} object. + * The outcome of the command from the server is returned in an {@link EslMessage} object. * * @param command API command to send * @param arg command arguments @@ -454,7 +454,7 @@ public class Client public void run() { try { /** - * Custom extra parsing to get conference Events for BigBlueButton / FreeSwitch intergration + * Custom extra parsing to get conference Events for BigBlueButton / FreeSwitch integration */ //FIXME: make the conference headers constants if (event.getEventSubclass().equals("conference::maintenance")) { @@ -495,7 +495,7 @@ public class Client listener.conferenceEventPlayFile(uniqueId, confName, confSize, event); return; } else if (eventFunc.equals("conf_api_sub_transfer") || eventFunc.equals("conference_api_sub_transfer")) { - //Member transfered to another conf... + //Member transferred to another conf... listener.conferenceEventTransfer(uniqueId, confName, confSize, event); return; } else if (eventFunc.equals("conference_add_member") || eventFunc.equals("conference_member_add")) { diff --git a/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/internal/debug/ChannelEventRunnable.java b/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/internal/debug/ChannelEventRunnable.java index 048d735dc5..8caf847ed4 100644 --- a/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/internal/debug/ChannelEventRunnable.java +++ b/bbb-fsesl-client/src/main/java/org/freeswitch/esl/client/internal/debug/ChannelEventRunnable.java @@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory; /** * a {@link Runnable} which sends the specified {@link ChannelEvent} upstream. * Most users will not see this type at all because it is used by - * {@link Executor} implementors only + * {@link Executor} implementers only * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) diff --git a/bbb-fsesl-client/src/test/java/org/freeswitch/esl/client/outbound/SocketClientTest.java b/bbb-fsesl-client/src/test/java/org/freeswitch/esl/client/outbound/SocketClientTest.java index 1fda52e6f0..4792639160 100644 --- a/bbb-fsesl-client/src/test/java/org/freeswitch/esl/client/outbound/SocketClientTest.java +++ b/bbb-fsesl-client/src/test/java/org/freeswitch/esl/client/outbound/SocketClientTest.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; * the following: *

     <extension>
-      <condition field="destination_number" expresssion="444">  
+      <condition field="destination_number" expression="444">
         <action application="socket" data="192.168.100.88:8084 async full"/>
       </condition>
     </extension>
diff --git a/bbb-graphql-actions/src/actions/meetingRecordingSetStatus.ts b/bbb-graphql-actions/src/actions/meetingRecordingSetStatus.ts
index d755129be7..10af9e82f7 100644
--- a/bbb-graphql-actions/src/actions/meetingRecordingSetStatus.ts
+++ b/bbb-graphql-actions/src/actions/meetingRecordingSetStatus.ts
@@ -21,7 +21,7 @@ export default function buildRedisMessage(sessionVariables: Record, input: Record): RedisMessage {
+  const eventName = `SendCursorPositionPubMsg`;
+
+  const routing = {
+    meetingId: sessionVariables['x-hasura-meetingid'] as String,
+    userId: sessionVariables['x-hasura-userid'] as String
+  };
+
+  const header = {
+    name: eventName,
+    meetingId: routing.meetingId,
+    userId: routing.userId
+  };
+
+  const body = {
+    whiteboardId: input.whiteboardId,
+    xPercent: input.xPercent,
+    yPercent: input.yPercent,
+  };
+
+  return { eventName, routing, header, body };
+}
diff --git a/bbb-graphql-middleware/bbb-graphql-middleware-config.env b/bbb-graphql-middleware/bbb-graphql-middleware-config.env
index 2c99921d5a..326bcf81d2 100644
--- a/bbb-graphql-middleware/bbb-graphql-middleware-config.env
+++ b/bbb-graphql-middleware/bbb-graphql-middleware-config.env
@@ -3,7 +3,7 @@ BBB_GRAPHQL_MIDDLEWARE_LISTEN_PORT=8378
 BBB_GRAPHQL_MIDDLEWARE_REDIS_ADDRESS=127.0.0.1:6379
 BBB_GRAPHQL_MIDDLEWARE_REDIS_PASSWORD=
 BBB_GRAPHQL_MIDDLEWARE_HASURA_WS=ws://127.0.0.1:8080/v1/graphql
-BBB_GRAPHQL_MIDDLEWARE_RATE_LIMIT_IN_MS=50
+BBB_GRAPHQL_MIDDLEWARE_MAX_CONN_PER_SECOND=10
 
 # If you are running a cluster proxy setup, you need to configure the Origin of
 # the frontend. See https://docs.bigbluebutton.org/administration/cluster-proxy
diff --git a/bbb-graphql-middleware/cmd/bbb-graphql-middleware/main.go b/bbb-graphql-middleware/cmd/bbb-graphql-middleware/main.go
index f7281418cf..e0ec58c4e0 100644
--- a/bbb-graphql-middleware/cmd/bbb-graphql-middleware/main.go
+++ b/bbb-graphql-middleware/cmd/bbb-graphql-middleware/main.go
@@ -2,12 +2,12 @@ package main
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"github.com/iMDT/bbb-graphql-middleware/internal/common"
 	"github.com/iMDT/bbb-graphql-middleware/internal/msgpatch"
 	"github.com/iMDT/bbb-graphql-middleware/internal/websrv"
 	log "github.com/sirupsen/logrus"
-	"golang.org/x/time/rate"
 	"net/http"
 	"os"
 	"strconv"
@@ -53,20 +53,23 @@ func main() {
 	}
 
 	//Define new Connections Rate Limit
-	rateLimitInMs := 50
-	if envRateLimitInMs := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_RATE_LIMIT_IN_MS"); envRateLimitInMs != "" {
-		if envRateLimitInMsAsInt, err := strconv.Atoi(envRateLimitInMs); err == nil {
-			rateLimitInMs = envRateLimitInMsAsInt
+	maxConnPerSecond := 10
+	if envMaxConnPerSecond := os.Getenv("BBB_GRAPHQL_MIDDLEWARE_MAX_CONN_PER_SECOND"); envMaxConnPerSecond != "" {
+		if envMaxConnPerSecondAsInt, err := strconv.Atoi(envMaxConnPerSecond); err == nil {
+			maxConnPerSecond = envMaxConnPerSecondAsInt
 		}
 	}
-	limiterInterval := rate.NewLimiter(rate.Every(time.Duration(rateLimitInMs)*time.Millisecond), 1)
+	rateLimiter := common.NewCustomRateLimiter(maxConnPerSecond)
 
 	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-		ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
+		ctx, cancel := context.WithTimeout(r.Context(), 120*time.Second)
 		defer cancel()
 
-		if err := limiterInterval.Wait(ctx); err != nil {
-			http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
+		if err := rateLimiter.Wait(ctx); err != nil {
+			if !errors.Is(err, context.Canceled) {
+				http.Error(w, "Request cancelled or rate limit exceeded", http.StatusTooManyRequests)
+			}
+
 			return
 		}
 
diff --git a/bbb-graphql-middleware/internal/common/CustomRateLimiter.go b/bbb-graphql-middleware/internal/common/CustomRateLimiter.go
new file mode 100644
index 0000000000..eb8235c134
--- /dev/null
+++ b/bbb-graphql-middleware/internal/common/CustomRateLimiter.go
@@ -0,0 +1,64 @@
+package common
+
+import (
+	"context"
+	"time"
+)
+
+type CustomRateLimiter struct {
+	tokens       chan struct{}
+	requestQueue chan context.Context
+}
+
+func NewCustomRateLimiter(requestsPerSecond int) *CustomRateLimiter {
+	rl := &CustomRateLimiter{
+		tokens:       make(chan struct{}, requestsPerSecond),
+		requestQueue: make(chan context.Context, 20000), // Adjust the size accordingly
+	}
+
+	go rl.refillTokens(requestsPerSecond)
+	go rl.processQueue()
+
+	return rl
+}
+
+func (rl *CustomRateLimiter) refillTokens(requestsPerSecond int) {
+	ticker := time.NewTicker(time.Second / time.Duration(requestsPerSecond))
+	for {
+		select {
+		case <-ticker.C:
+			// Try to add a token, skip if full
+			select {
+			case rl.tokens <- struct{}{}:
+			default:
+			}
+		}
+	}
+}
+
+func (rl *CustomRateLimiter) processQueue() {
+	for ctx := range rl.requestQueue {
+		select {
+		case <-rl.tokens:
+			if ctx.Err() == nil {
+				// Token acquired and context not cancelled, proceed
+				// Simulate processing by calling a dummy function
+				// processRequest() or similar
+			}
+		case <-ctx.Done():
+			// Context cancelled, skip
+		}
+	}
+}
+
+func (rl *CustomRateLimiter) Wait(ctx context.Context) error {
+	rl.requestQueue <- ctx
+	select {
+	case <-ctx.Done():
+		// Request cancelled
+		return ctx.Err()
+	case <-rl.tokens:
+		// Acquired token, proceed
+		return nil
+	}
+}
diff --git a/bbb-graphql-middleware/internal/hascli/conn/reader/reader.go b/bbb-graphql-middleware/internal/hascli/conn/reader/reader.go
index 73d302cf29..528b30b72b 100644
--- a/bbb-graphql-middleware/internal/hascli/conn/reader/reader.go
+++ b/bbb-graphql-middleware/internal/hascli/conn/reader/reader.go
@@ -54,7 +54,7 @@ func handleMessageReceivedFromHasura(hc *common.HasuraConnection, fromHasuraToBr
 			subscription, ok := hc.BrowserConn.ActiveSubscriptions[queryId]
 			hc.BrowserConn.ActiveSubscriptionsMutex.RUnlock()
 			if !ok {
-				log.Debugf("Subscription with Id %s doesn't exist anymore, skiping response.", queryId)
+				log.Debugf("Subscription with Id %s doesn't exist anymore, skipping response.", queryId)
 				return
 			}
 
diff --git a/bbb-graphql-middleware/internal/websrv/connhandler.go b/bbb-graphql-middleware/internal/websrv/connhandler.go
index 33e925aece..256f385e99 100644
--- a/bbb-graphql-middleware/internal/websrv/connhandler.go
+++ b/bbb-graphql-middleware/internal/websrv/connhandler.go
@@ -67,10 +67,13 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) {
 	defer func() {
 		msgpatch.RemoveConnCacheDir(browserConnectionId)
 		BrowserConnectionsMutex.Lock()
-		sessionTokenRemoved := BrowserConnections[browserConnectionId].SessionToken
-		delete(BrowserConnections, browserConnectionId)
+		_, bcExists := BrowserConnections[browserConnectionId]
+		if bcExists {
+			sessionTokenRemoved := BrowserConnections[browserConnectionId].SessionToken
+			delete(BrowserConnections, browserConnectionId)
+			go SendUserGraphqlConnectionClosedSysMsg(sessionTokenRemoved, browserConnectionId)
+		}
 		BrowserConnectionsMutex.Unlock()
-		go SendUserGraphqlConnectionClosedSysMsg(sessionTokenRemoved, browserConnectionId)
 
 		log.Infof("connection removed")
 	}()
@@ -135,7 +138,71 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) {
 
 func InvalidateSessionTokenConnections(sessionTokenToInvalidate string) {
 	BrowserConnectionsMutex.RLock()
+	connectionsToProcess := make([]*common.BrowserConnection, 0)
 	for _, browserConnection := range BrowserConnections {
+		if browserConnection.SessionToken == sessionTokenToInvalidate {
+			connectionsToProcess = append(connectionsToProcess, browserConnection)
+		}
+	}
+	BrowserConnectionsMutex.RUnlock()
+
+	var wg sync.WaitGroup
+	for _, browserConnection := range connectionsToProcess {
+		wg.Add(1)
+		go func(bc *common.BrowserConnection) {
+			defer wg.Done()
+			invalidateBrowserConnection(bc, sessionTokenToInvalidate)
+		}(browserConnection)
+	}
+	wg.Wait()
+}
+
+func invalidateBrowserConnection(bc *common.BrowserConnection, sessionToken string) {
+	if bc.HasuraConnection == nil {
+		return // If there's no Hasura connection, there's nothing to invalidate.
+	}
+
+	hasuraConnectionId := bc.HasuraConnection.Id
+
+	// Send message to stop receiving new messages from the browser.
+	bc.HasuraConnection.FreezeMsgFromBrowserChan.Send(true)
+
+	// Wait until there are no active mutations.
+	for iterationCount := 0; iterationCount < 20; iterationCount++ {
+		activeMutationFound := false
+		bc.ActiveSubscriptionsMutex.RLock()
+		for _, subscription := range bc.ActiveSubscriptions {
+			if subscription.Type == common.Mutation {
+				activeMutationFound = true
+				break
+			}
+		}
+		bc.ActiveSubscriptionsMutex.RUnlock()
+
+		if !activeMutationFound {
+			break // Exit the loop if no active mutations are found.
+		}
+		time.Sleep(100 * time.Millisecond) // Wait a bit before checking again.
+	}
+
+	log.Debugf("Processing invalidate request for sessionToken %v (hasura connection %v)", sessionToken, hasuraConnectionId)
+
+	// Cancel the Hasura connection context to clean up resources.
+	if bc.HasuraConnection != nil && bc.HasuraConnection.ContextCancelFunc != nil {
+		bc.HasuraConnection.ContextCancelFunc()
+	}
+
+	log.Debugf("Processed invalidate request for sessionToken %v (hasura connection %v)", sessionToken, hasuraConnectionId)
+
+	// Send a reconnection confirmation message
+	go SendUserGraphqlReconnectionForcedEvtMsg(sessionToken)
+}
+
+func InvalidateSessionTokenConnectionsB(sessionTokenToInvalidate string) {
+	BrowserConnectionsMutex.RLock()
+	for _, browserConnection := range BrowserConnections {
+		hasuraConnectionId := browserConnection.HasuraConnection.Id
+
 		if browserConnection.SessionToken == sessionTokenToInvalidate {
 			if browserConnection.HasuraConnection != nil {
 				//Send message to force stop receiving new messages from the browser
@@ -159,9 +226,10 @@ func InvalidateSessionTokenConnections(sessionTokenToInvalidate string) {
 					time.Sleep(100 * time.Millisecond)
 				}
 
-				hasuraConnectionId := browserConnection.HasuraConnection.Id
 				log.Debugf("Processing invalidate request for sessionToken %v (hasura connection %v)", sessionTokenToInvalidate, hasuraConnectionId)
-				browserConnection.HasuraConnection.ContextCancelFunc()
+				if browserConnection.HasuraConnection != nil {
+					browserConnection.HasuraConnection.ContextCancelFunc()
+				}
 				log.Debugf("Processed invalidate request for sessionToken %v (hasura connection %v)", sessionTokenToInvalidate, hasuraConnectionId)
 
 				go SendUserGraphqlReconnectionForcedEvtMsg(browserConnection.SessionToken)
diff --git a/bbb-graphql-middleware/internal/websrv/reader/reader.go b/bbb-graphql-middleware/internal/websrv/reader/reader.go
index 20ddbf8f07..6d754e4b62 100644
--- a/bbb-graphql-middleware/internal/websrv/reader/reader.go
+++ b/bbb-graphql-middleware/internal/websrv/reader/reader.go
@@ -39,7 +39,7 @@ func BrowserConnectionReader(browserConnectionId string, ctx context.Context, ct
 			if errors.Is(err, context.Canceled) {
 				log.Debugf("Closing Browser ws connection as Context was cancelled!")
 			} else {
-				log.Debugf("Hasura is disconnected, skiping reading of ws message: %v", err)
+				log.Debugf("Hasura is disconnected, skipping reading of ws message: %v", err)
 			}
 			return
 		}
diff --git a/bbb-graphql-middleware/internal/websrv/writer/writer.go b/bbb-graphql-middleware/internal/websrv/writer/writer.go
index b168f95492..b478ba61fa 100644
--- a/bbb-graphql-middleware/internal/websrv/writer/writer.go
+++ b/bbb-graphql-middleware/internal/websrv/writer/writer.go
@@ -35,7 +35,7 @@ RangeLoop:
 				log.Tracef("sending to browser: %v", toBrowserMessage)
 				err := wsjson.Write(ctx, browserWsConn, toBrowserMessage)
 				if err != nil {
-					log.Debugf("Browser is disconnected, skiping writing of ws message: %v", err)
+					log.Debugf("Browser is disconnected, skipping writing of ws message: %v", err)
 					return
 				}
 
diff --git a/bbb-graphql-server/bbb_schema.sql b/bbb-graphql-server/bbb_schema.sql
index 84e223d64e..ae3de501ec 100644
--- a/bbb-graphql-server/bbb_schema.sql
+++ b/bbb-graphql-server/bbb_schema.sql
@@ -250,7 +250,7 @@ CREATE TABLE "user" (
     "registeredOn" bigint,
     "excludeFromDashboard" bool,
     "enforceLayout" varchar(50),
-    --columns of user state bellow
+    --columns of user state below
     "raiseHand" bool default false,
     "raiseHandTime" timestamp with time zone,
     "away" bool default false,
diff --git a/bbb-graphql-server/metadata/actions.graphql b/bbb-graphql-server/metadata/actions.graphql
index 610764bdb8..1817ef77a0 100644
--- a/bbb-graphql-server/metadata/actions.graphql
+++ b/bbb-graphql-server/metadata/actions.graphql
@@ -287,6 +287,14 @@ type Mutation {
   ): Boolean
 }
 
+type Mutation {
+  presentationPublishCursor(
+    whiteboardId: String!
+    xPercent: Float!
+    yPercent: Float!
+  ): Boolean
+}
+
 type Mutation {
   presentationRemove(
     presentationId: String!
diff --git a/bbb-graphql-server/metadata/actions.yaml b/bbb-graphql-server/metadata/actions.yaml
index 7ca848b2fe..f12b77a86f 100644
--- a/bbb-graphql-server/metadata/actions.yaml
+++ b/bbb-graphql-server/metadata/actions.yaml
@@ -252,6 +252,12 @@ actions:
     permissions:
       - role: bbb_client
     comment: presentationExport
+  - name: presentationPublishCursor
+    definition:
+      kind: synchronous
+      handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}'
+    permissions:
+      - role: bbb_client
   - name: presentationRemove
     definition:
       kind: synchronous
diff --git a/bbb-libreoffice/assets/convert-cool.sh b/bbb-libreoffice/assets/convert-cool.sh
index 918fa79b85..8cf889df8f 100644
--- a/bbb-libreoffice/assets/convert-cool.sh
+++ b/bbb-libreoffice/assets/convert-cool.sh
@@ -16,7 +16,7 @@ HOST=127.0.0.1
 
 # Set this to "-k" to allow it to work in a test environment, ie with a self signed
 # certificate
-UNSECURE=
+INSECURE=
 
 # This script receives three params
 # Param 1: Input office file path (e.g. "/tmp/test.odt")
@@ -46,6 +46,6 @@ timeoutSecs="${timeoutSecs:0:3}"
 
 # The timeout is important.
 
-timeout $(printf %03d $timeoutSecs)s curl $UNSECURE -F "data=@${source}" https://$HOST:9980/cool/convert-to/$convertTo > "${dest}"
+timeout $(printf %03d $timeoutSecs)s curl $INSECURE -F "data=@${source}" https://$HOST:9980/cool/convert-to/$convertTo > "${dest}"
 
 exit 0
diff --git a/bbb-voice-conference/config/freeswitch/README b/bbb-voice-conference/config/freeswitch/README
index da93b0673a..59ada7b187 100644
--- a/bbb-voice-conference/config/freeswitch/README
+++ b/bbb-voice-conference/config/freeswitch/README
@@ -18,7 +18,7 @@ conf.orig dir is what was installed by freeswitch by default
 
 NOTE: you must double check this config if you intend to have 
  the freeswitch server on a public facing interface. 
- It defaults to localhost for the event socket inteface.
+ It defaults to localhost for the event socket interface.
 
  I run my server in a test environment with 
   /usr/local/freeswitch/bin/freeswitch -hp -nc
diff --git a/bbb-voice-conference/config/freeswitch/conf/dialplan/default.xml b/bbb-voice-conference/config/freeswitch/conf/dialplan/default.xml
index 65bedaa1bc..f094cab720 100644
--- a/bbb-voice-conference/config/freeswitch/conf/dialplan/default.xml
+++ b/bbb-voice-conference/config/freeswitch/conf/dialplan/default.xml
@@ -3,7 +3,7 @@
     NOTICE:
 
     This context is usually accessed via authenticated callers on the sip profile on port 5060
-    or transfered callers from the public context which arrived via the sip profile on port 5080.
+    or transferred callers from the public context which arrived via the sip profile on port 5080.
 
     Authenticated users will use the user_context variable on the user to determine what context
     they can access.  You can also add a user in the directory with the cidr= attribute acl.conf.xml
diff --git a/bbb-voice-conference/config/freeswitch/conf/directory/default/bbbuser.xml b/bbb-voice-conference/config/freeswitch/conf/directory/default/bbbuser.xml
index 2c6afc72fe..4d584e3061 100644
--- a/bbb-voice-conference/config/freeswitch/conf/directory/default/bbbuser.xml
+++ b/bbb-voice-conference/config/freeswitch/conf/directory/default/bbbuser.xml
@@ -7,7 +7,7 @@
     
       
       
-      
+      
       
     
     
diff --git a/bbb-voice-conference/config/freeswitch/conf/sip_profiles/internal.xml b/bbb-voice-conference/config/freeswitch/conf/sip_profiles/internal.xml
index b9a9f68a3c..b8a4149d4c 100644
--- a/bbb-voice-conference/config/freeswitch/conf/sip_profiles/internal.xml
+++ b/bbb-voice-conference/config/freeswitch/conf/sip_profiles/internal.xml
@@ -327,7 +327,7 @@
     
     
 
-    
+    
     
 
     
diff --git a/bbb-voice-conference/config/freeswitch/conf/vars.xml b/bbb-voice-conference/config/freeswitch/conf/vars.xml
index 7590067ca3..aab194e167 100644
--- a/bbb-voice-conference/config/freeswitch/conf/vars.xml
+++ b/bbb-voice-conference/config/freeswitch/conf/vars.xml
@@ -166,7 +166,7 @@
 
       rtp_secure_media_suites
       ____________________________________________________________________________
-      Optionaly you can use rtp_secure_media_suites to dictate the suite list
+      Optionally you can use rtp_secure_media_suites to dictate the suite list
       and only use rtp_secure_media=[optional|mandatory|false|true] without having
       to dictate the suite list with the rtp_secure_media* variables.
   -->
@@ -175,7 +175,7 @@
 
        codecname[@8000h|16000h|32000h[@XXi]]
 
-       XX is the frame size must be multples allowed for the codec
+       XX is the frame size must be multiples allowed for the codec
        FreeSWITCH can support 10-120ms on some codecs.
        We do not support exceeding the MTU of the RTP packet.
 
@@ -414,7 +414,7 @@
 
      openssl ciphers -v 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH'
 
-     Will show you what is available in your verion of openssl.
+     Will show you what is available in your version of openssl.
   -->
   
 
@@ -431,7 +431,7 @@
   
 
   
-  
+  
   
   
 
diff --git a/bbb-webrtc-sfu.placeholder.sh b/bbb-webrtc-sfu.placeholder.sh
index 0b7b4d076e..e94cdce28c 100755
--- a/bbb-webrtc-sfu.placeholder.sh
+++ b/bbb-webrtc-sfu.placeholder.sh
@@ -1 +1 @@
-git clone --branch v2.13.2 --depth 1 https://github.com/bigbluebutton/bbb-webrtc-sfu bbb-webrtc-sfu
+git clone --branch v2.13.3 --depth 1 https://github.com/bigbluebutton/bbb-webrtc-sfu bbb-webrtc-sfu
diff --git a/bigbluebutton-config/bin/bbb-conf b/bigbluebutton-config/bin/bbb-conf
index 56ec86e159..99cc73c972 100755
--- a/bigbluebutton-config/bin/bbb-conf
+++ b/bigbluebutton-config/bin/bbb-conf
@@ -308,7 +308,7 @@ check_and_backup () {
     fi
 }
 
-# 3 paramenter: the file, the variable name, the new value
+# 3 parameter: the file, the variable name, the new value
 change_var_value () {
     check_and_backup $1
     sed -i "s<^[[:blank:]#]*\(${2}\).*<\1=${3}<" $1
@@ -1489,7 +1489,7 @@ if [ -n "$HOST" ]; then
         echo "bigbluebutton.web.serverURL=$PROTOCOL://$HOST" >> "$BBB_WEB_ETC_CONFIG"
     fi
 
-    # Populate /etc/bigbluebutton/bbb-web.properites with the shared secret
+    # Populate /etc/bigbluebutton/bbb-web.properties with the shared secret
     if ! grep -q "^securitySalt" "$BBB_WEB_ETC_CONFIG"; then
         echo "securitySalt=$(get_bbb_web_config_value securitySalt)" >> "$BBB_WEB_ETC_CONFIG"
     fi
diff --git a/bigbluebutton-config/bin/bbb-record b/bigbluebutton-config/bin/bbb-record
index 8e5bf5bcec..f1efa5ec73 100755
--- a/bigbluebutton-config/bin/bbb-record
+++ b/bigbluebutton-config/bin/bbb-record
@@ -23,7 +23,7 @@
 #       Daniel Petri Rocha 
 #
 # Changelog:
-#   2011-08-18 FFD  Inital Version
+#   2011-08-18 FFD  Initial Version
 #   2011-11-20 FFD  Added more checks for processing of recording
 #   2012-01-04 GUG  Add option to check for errors
 #   2012-02-27 GUG  Add option to delete one meeting and recording
diff --git a/bigbluebutton-config/cron.daily/bigbluebutton b/bigbluebutton-config/cron.daily/bigbluebutton
index 30fadb16f8..d643230806 100755
--- a/bigbluebutton-config/cron.daily/bigbluebutton
+++ b/bigbluebutton-config/cron.daily/bigbluebutton
@@ -122,7 +122,7 @@ remove_raw_of_published_recordings(){
 remove_raw_of_published_recordings
 
 #
-# Remove untagged and unamed docker images, cleanning /var/lib/docker/overlay2
+# Remove untagged and unnamed docker images, cleaning /var/lib/docker/overlay2
 #
 docker image prune -f
 
diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/service.js b/bigbluebutton-html5/imports/api/audio/client/bridge/service.js
index d795db4393..62a9dced72 100644
--- a/bigbluebutton-html5/imports/api/audio/client/bridge/service.js
+++ b/bigbluebutton-html5/imports/api/audio/client/bridge/service.js
@@ -97,7 +97,7 @@ const doGUM = async (constraints, retryOnFailure = false) => {
     const stream = await navigator.mediaDevices.getUserMedia(constraints);
     return stream;
   } catch (error) {
-    // This is probably a deviceId mistmatch. Retry with base constraints
+    // This is probably a deviceId mismatch. Retry with base constraints
     // without an exact deviceId.
     if (error.name === 'OverconstrainedError' && retryOnFailure) {
       logger.warn({
diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/sfu-audio-bridge.js b/bigbluebutton-html5/imports/api/audio/client/bridge/sfu-audio-bridge.js
index e26fec57c7..dacdbc1a50 100755
--- a/bigbluebutton-html5/imports/api/audio/client/bridge/sfu-audio-bridge.js
+++ b/bigbluebutton-html5/imports/api/audio/client/bridge/sfu-audio-bridge.js
@@ -225,7 +225,7 @@ export default class SFUAudioBridge extends BaseAudioBridge {
         }
       }
 
-      // Already tried reconnecting once OR the user handn't succesfully
+      // Already tried reconnecting once OR the user handn't successfully
       // connected firsthand and retrying isn't an option. Finish the session
       // and reject with the error
       logger.error({
diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
index e7f013c9b7..4f90d5d998 100755
--- a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
+++ b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
@@ -272,7 +272,7 @@ class SIPSession {
     *
     * sessionSupportRTPPayloadDtmf
     * tells if browser support RFC4733 DTMF.
-    * Safari 13 doens't support it yet
+    * Safari 13 doesn't support it yet
     */
   sessionSupportRTPPayloadDtmf(session) {
     try {
@@ -383,7 +383,7 @@ class SIPSession {
     if (this.preloadedInputStream && this.preloadedInputStream.active) {
       return Promise.resolve(this.preloadedInputStream);
     }
-    // The rest of this mimicks the default factory behavior.
+    // The rest of this mimics the default factory behavior.
     if (!constraints.audio && !constraints.video) {
       return Promise.resolve(new MediaStream());
     }
@@ -498,7 +498,7 @@ class SIPSession {
                 extraInfo: {
                   callerIdName: this.user.callerIdName,
                 },
-              }, 'User agent succesfully reconnected');
+              }, 'User agent successfully reconnected');
             }).catch(() => {
               if (userAgentConnected) {
                 error = 1001;
@@ -531,7 +531,7 @@ class SIPSession {
           extraInfo: {
             callerIdName: this.user.callerIdName,
           },
-        }, 'User agent succesfully connected');
+        }, 'User agent successfully connected');
 
         window.addEventListener('beforeunload', this.onBeforeUnload.bind(this));
 
@@ -567,7 +567,7 @@ class SIPSession {
             extraInfo: {
               callerIdName: this.user.callerIdName,
             },
-          }, 'User agent succesfully reconnected');
+          }, 'User agent successfully reconnected');
 
           resolve();
         }).catch(() => {
@@ -579,7 +579,7 @@ class SIPSession {
               callerIdName: this.user.callerIdName,
             },
           }, 'User agent failed to reconnect after'
-          + ` ${USER_AGENT_RECONNECTION_ATTEMPTS} attemps`);
+          + ` ${USER_AGENT_RECONNECTION_ATTEMPTS} attempts`);
 
           this.callback({
             status: this.baseCallStates.failed,
@@ -1013,7 +1013,7 @@ class SIPSession {
         }
 
         // if session hasn't even started, we let audio-modal to handle
-        // any possile errors
+        // any possible errors
         if (!this._currentSessionState) return false;
 
 
diff --git a/bigbluebutton-html5/imports/api/cursor/index.js b/bigbluebutton-html5/imports/api/cursor/index.js
deleted file mode 100755
index e69de29bb2..0000000000
diff --git a/bigbluebutton-html5/imports/api/cursor/server/index.js b/bigbluebutton-html5/imports/api/cursor/server/index.js
deleted file mode 100755
index ba55c4a16e..0000000000
--- a/bigbluebutton-html5/imports/api/cursor/server/index.js
+++ /dev/null
@@ -1 +0,0 @@
-import './methods';
diff --git a/bigbluebutton-html5/imports/api/cursor/server/methods.js b/bigbluebutton-html5/imports/api/cursor/server/methods.js
deleted file mode 100644
index f64fb9677e..0000000000
--- a/bigbluebutton-html5/imports/api/cursor/server/methods.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import { Meteor } from 'meteor/meteor';
-import publishCursorUpdate from './methods/publishCursorUpdate';
-
-Meteor.methods({
-  publishCursorUpdate,
-});
diff --git a/bigbluebutton-html5/imports/api/cursor/server/methods/publishCursorUpdate.js b/bigbluebutton-html5/imports/api/cursor/server/methods/publishCursorUpdate.js
deleted file mode 100755
index 0ee0dbc411..0000000000
--- a/bigbluebutton-html5/imports/api/cursor/server/methods/publishCursorUpdate.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import RedisPubSub from '/imports/startup/server/redis';
-import { Meteor } from 'meteor/meteor';
-
-export default function publishCursorUpdate(meetingId, requesterUserId, payload) {
-  const REDIS_CONFIG = Meteor.settings.private.redis;
-  const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
-  const EVENT_NAME = 'SendCursorPositionPubMsg';
-
-  return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
-}
diff --git a/bigbluebutton-html5/imports/api/meetings/server/modifiers/updateRandomViewer.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/updateRandomViewer.js
index 2336b201a1..c1dbc02f50 100644
--- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/updateRandomViewer.js
+++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/updateRandomViewer.js
@@ -8,7 +8,7 @@ const SELECT_RANDOM_USER_COUNTDOWN = Meteor.settings.public.selectRandomUser.cou
 //  for iteration in animation.
 const intervals = [0, 200, 450, 750, 1100, 1500];
 
-//  Used to togle to the first value of intervals to
+//  Used to toggle to the first value of intervals to
 //  differenciare whether this function has been called
 let updateIndicator = true;
 
@@ -30,7 +30,7 @@ function getFiveRandom(userList, userIds) {
       IDs = userIds.slice(); // start over
       let userId = IDs.splice(0, 1);
       if (userList[userList.length] === [userId, intervals[i]]) {
-        // If we start over with the one we finnished, change it
+        // If we start over with the one we finished, change it
         IDs.push(userId);
         userId = IDs.splice(0, 1);
       }
diff --git a/bigbluebutton-html5/imports/ui/components/app/component.jsx b/bigbluebutton-html5/imports/ui/components/app/component.jsx
index 7d73cde95a..5bc10b25bb 100644
--- a/bigbluebutton-html5/imports/ui/components/app/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/app/component.jsx
@@ -118,7 +118,7 @@ const intlMessages = defineMessages({
   },
   defaultViewLabel: {
     id: 'app.title.defaultViewLabel',
-    description: 'view name apended to document title',
+    description: 'view name appended to document title',
   },
   promotedLabel: {
     id: 'app.toast.promotedLabel',
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-modal/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-modal/component.jsx
index d32f988e43..c581df00c3 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-modal/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-modal/component.jsx
@@ -626,7 +626,7 @@ class AudioModal extends Component {
             
               Chrome,
                   1: Firefox,
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
index 40372c7d64..86744ac539 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
@@ -208,7 +208,7 @@ class AudioSettings extends React.Component {
     const { outputDeviceId: currentOutputDeviceId } = this.state;
 
     // withEcho usage (isLive arg): if local echo is enabled we need the device
-    // change to be performed seamlessly (which is what the isLive parameter guarantes)
+    // change to be performed seamlessly (which is what the isLive parameter guarantees)
     changeOutputDevice(deviceId, withEcho)
       .then(() => {
         this.setState({
diff --git a/bigbluebutton-html5/imports/ui/components/audio/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/container.jsx
index 6b15ae1526..c8cbf1c8d9 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/container.jsx
@@ -67,11 +67,11 @@ const intlMessages = defineMessages({
   },
   BrowserNotSupported: {
     id: 'app.audioNotification.audioFailedError1003',
-    description: 'browser not supported error messsage',
+    description: 'browser not supported error message',
   },
   reconectingAsListener: {
     id: 'app.audioNotificaion.reconnectingAsListenOnly',
-    description: 'ice negociation error messsage',
+    description: 'ice negotiation error message',
   },
 });
 
diff --git a/bigbluebutton-html5/imports/ui/components/captions/component.jsx b/bigbluebutton-html5/imports/ui/components/captions/component.jsx
index 3b5f4a5a82..ad6c3de9b1 100644
--- a/bigbluebutton-html5/imports/ui/components/captions/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/captions/component.jsx
@@ -29,7 +29,7 @@ const intlMessages = defineMessages({
   },
   dictationStop: {
     id: 'app.captions.dictationStop',
-    description: 'Label for stoping speech recognition',
+    description: 'Label for stopping speech recognition',
   },
   dictationOnDesc: {
     id: 'app.captions.dictationOnDesc',
diff --git a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-popup/component.tsx b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-popup/component.tsx
index 4819efc6a7..35cd501073 100644
--- a/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-popup/component.tsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/chat-graphql/chat-popup/component.tsx
@@ -29,7 +29,7 @@ const isBoolean = (v: unknown): boolean => {
   } if (v === 'false') {
     return false;
   }
-  // if v is not difined it shouldn't be considered on comparation, so it returns true
+  // if v is not defined it shouldn't be considered on comparison, so it returns true
   return true;
 };
 
diff --git a/bigbluebutton-html5/imports/ui/components/common/modal/random-user/container.jsx b/bigbluebutton-html5/imports/ui/components/common/modal/random-user/container.jsx
index d7c8f29a71..f2920f53e5 100644
--- a/bigbluebutton-html5/imports/ui/components/common/modal/random-user/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/common/modal/random-user/container.jsx
@@ -46,7 +46,7 @@ const RandomUserSelectContainer = (props) => {
   try {
     if (!currentUser.presenter //  this functionality does not bother presenter
       && (!keepModalOpen) //  we only ween a change if modal has been closed before
-      && (randomlySelectedUser[0][1] !== updateIndicator)// if tey are different, a user was generated
+      && (randomlySelectedUser[0][1] !== updateIndicator)// if they are different, a user was generated
     ) { keepModalOpen = true; } //  reopen modal
     if (!currentUser.presenter) { updateIndicator = randomlySelectedUser[0][1]; } // keep indicator up to date
   } catch (err) {
diff --git a/bigbluebutton-html5/imports/ui/components/connection-manager/component.tsx b/bigbluebutton-html5/imports/ui/components/connection-manager/component.tsx
index 6066c7e35c..eb583db354 100644
--- a/bigbluebutton-html5/imports/ui/components/connection-manager/component.tsx
+++ b/bigbluebutton-html5/imports/ui/components/connection-manager/component.tsx
@@ -56,6 +56,7 @@ const ConnectionManager: React.FC = ({ children }): Reac
         const subscription = new SubscriptionClient(graphqlUrl, {
           reconnect: true,
           timeout: 30000,
+          minTimeout: 30000,
           connectionParams: {
             headers: {
               'X-Session-Token': sessionToken,
diff --git a/bigbluebutton-html5/imports/ui/components/connection-manager/startup-data-fetch/component.tsx b/bigbluebutton-html5/imports/ui/components/connection-manager/startup-data-fetch/component.tsx
index f3d34eee6f..da1d4c277d 100644
--- a/bigbluebutton-html5/imports/ui/components/connection-manager/startup-data-fetch/component.tsx
+++ b/bigbluebutton-html5/imports/ui/components/connection-manager/startup-data-fetch/component.tsx
@@ -1,4 +1,5 @@
 import React, { useEffect } from 'react';
+import { Session } from 'meteor/session';
 import { ErrorScreen } from '../../error-screen/component';
 import LoadingScreen from '../../common/loading-screen/component';
 
@@ -69,6 +70,10 @@ const StartupDataFetch: React.FC = ({
         setSettingsFetched(true);
         clearTimeout(timeoutRef.current);
         setLoading(false);
+      }).catch(() => {
+        Session.set('errorMessageDescription', 'meeting_ended');
+        setError('Error fetching startup data');
+        setLoading(false);
       });
   }, []);
 
@@ -79,6 +84,7 @@ const StartupDataFetch: React.FC = ({
         ? (
           
         )
         : null}
diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx
index d978d1a300..15ce38441f 100644
--- a/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/connection-status/modal/component.jsx
@@ -30,7 +30,7 @@ const intlMessages = defineMessages({
   },
   more: {
     id: 'app.connection-status.more',
-    description: 'More about conectivity issues',
+    description: 'More about connectivity issues',
   },
   audioLabel: {
     id: 'app.settings.audioTab.label',
@@ -386,7 +386,7 @@ class ConnectionStatusComponent extends PureComponent {
   }
 
   /**
-   * Render network data , containing information abount current upload and
+   * Render network data , containing information about current upload and
    * download rates
    * @return {Object} The component to be renderized.
    */
diff --git a/bigbluebutton-html5/imports/ui/components/connection-status/service.js b/bigbluebutton-html5/imports/ui/components/connection-status/service.js
index 6250527270..7022785682 100644
--- a/bigbluebutton-html5/imports/ui/components/connection-status/service.js
+++ b/bigbluebutton-html5/imports/ui/components/connection-status/service.js
@@ -263,7 +263,7 @@ const getNetworkData = async () => {
 };
 
 /**
- * Calculates both upload and download rates using data retreived from getStats
+ * Calculates both upload and download rates using data retrieved from getStats
  * API. For upload (outbound-rtp) we use both bytesSent and timestamp fields.
  * byteSent field contains the number of octets sent at the given timestamp,
  * more information can be found in:
diff --git a/bigbluebutton-html5/imports/ui/components/layout/context.jsx b/bigbluebutton-html5/imports/ui/components/layout/context.jsx
index 469f09b1ff..b5f1fce7aa 100644
--- a/bigbluebutton-html5/imports/ui/components/layout/context.jsx
+++ b/bigbluebutton-html5/imports/ui/components/layout/context.jsx
@@ -94,7 +94,7 @@ const reducer = (state, action) => {
     }
 
     // LAYOUT TYPE
-    // using to load a diferent layout manager
+    // using to load a different layout manager
     case ACTIONS.SET_LAYOUT_TYPE: {
       const { layoutType } = state.input;
       if (layoutType === action.value) return state;
diff --git a/bigbluebutton-html5/imports/ui/components/layout/modal/component.jsx b/bigbluebutton-html5/imports/ui/components/layout/modal/component.jsx
index b8aad92ce2..4a5b25b4e5 100644
--- a/bigbluebutton-html5/imports/ui/components/layout/modal/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/layout/modal/component.jsx
@@ -22,7 +22,7 @@ const LayoutModalComponent = (props) => {
 
   const [selectedLayout, setSelectedLayout] = useState(application.selectedLayout);
 
-  const BASE_NAME = window.meetingClientSettings.public.app.basename;
+  const BASE_NAME = window.meetingClientSettings.public.app.cdn + window.meetingClientSettings.public.app.basename;
 
   const LAYOUTS_PATH = `${BASE_NAME}/resources/images/layouts/`;
   const isKeepPushingLayoutEnabled = SettingsService.isKeepPushingLayoutEnabled();
diff --git a/bigbluebutton-html5/imports/ui/components/layout/utils.js b/bigbluebutton-html5/imports/ui/components/layout/utils.js
index 26c8c98a26..12c62b82f2 100644
--- a/bigbluebutton-html5/imports/ui/components/layout/utils.js
+++ b/bigbluebutton-html5/imports/ui/components/layout/utils.js
@@ -23,7 +23,7 @@ export {
   isMobile, isTablet, isTabletPortrait, isTabletLandscape, isDesktop,
 };
 
-// Array for select component to select diferent layout
+// Array for select component to select different layout
 const suportedLayouts = [
   {
     layoutKey: LAYOUT_TYPE.SMART_LAYOUT,
diff --git a/bigbluebutton-html5/imports/ui/components/legacy/component.jsx b/bigbluebutton-html5/imports/ui/components/legacy/component.jsx
index 56e572eaab..a59254120f 100755
--- a/bigbluebutton-html5/imports/ui/components/legacy/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/legacy/component.jsx
@@ -167,7 +167,7 @@ export default class Legacy extends Component {
             

Chrome, 1: Firefox, diff --git a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx index d8daa5e90c..822d13e5be 100755 --- a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx @@ -68,7 +68,7 @@ const intlMessage = defineMessages({ }, confirmDesc: { id: 'app.leaveConfirmation.confirmDesc', - description: 'adds context to confim option', + description: 'adds context to confirm option', }, sendLabel: { id: 'app.feedback.sendFeedback', diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/talking-indicator/queries.ts b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/talking-indicator/queries.ts index d64313f983..c768f5d00b 100644 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/talking-indicator/queries.ts +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/nav-bar-graphql/talking-indicator/queries.ts @@ -9,7 +9,7 @@ export interface IsBreakoutSubscriptionData { meeting: Array; } -// TODO: rework when useMeeting hook be avaible +// TODO: rework when useMeeting hook be available export const MEETING_ISBREAKOUT_SUBSCRIPTION = gql` subscription getIsBreakout { meeting { diff --git a/bigbluebutton-html5/imports/ui/components/poll/component.jsx b/bigbluebutton-html5/imports/ui/components/poll/component.jsx index 6b73f3306c..7dcefaaa74 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/poll/component.jsx @@ -62,7 +62,7 @@ const intlMessages = defineMessages({ }, customInputToggleLabel: { id: 'app.poll.customInput.label', - description: 'poll custom input toogle button label', + description: 'poll custom input toggle button label', }, customInputInstructionsLabel: { id: 'app.poll.customInputInstructions.label', diff --git a/bigbluebutton-html5/imports/ui/components/poll/container.jsx b/bigbluebutton-html5/imports/ui/components/poll/container.jsx index ec008f01f8..a4d4db4e23 100644 --- a/bigbluebutton-html5/imports/ui/components/poll/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/poll/container.jsx @@ -11,7 +11,7 @@ import { POLL_PUBLISH_RESULT, POLL_CANCEL, POLL_CREATE } from './mutations'; import { ACTIONS, PANELS } from '../layout/enums'; const CHAT_CONFIG = window.meetingClientSettings.public.chat; -const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_id; +const PUBLIC_CHAT_KEY = CHAT_CONFIG.public_group_id; const PollContainer = (props) => { const layoutContextDispatch = layoutDispatch(); diff --git a/bigbluebutton-html5/imports/ui/components/presentation/mutations.jsx b/bigbluebutton-html5/imports/ui/components/presentation/mutations.jsx index e5d082205e..fb79ee17a2 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/mutations.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/mutations.jsx @@ -90,6 +90,16 @@ export const PRES_ANNOTATION_SUBMIT = gql` } `; +export const PRESENTATION_PUBLISH_CURSOR = gql` + mutation PresentationPublishCursor($whiteboardId: String!, $xPercent: Float!, $yPercent: Float!) { + presentationPublishCursor( + whiteboardId: $whiteboardId, + xPercent: $xPercent, + yPercent: $yPercent, + ) + } +`; + export default { PRESENTATION_SET_ZOOM, PRESENTATION_SET_WRITERS, @@ -100,4 +110,5 @@ export default { PRESENTATION_REMOVE, PRES_ANNOTATION_DELETE, PRES_ANNOTATION_SUBMIT, + PRESENTATION_PUBLISH_CURSOR, }; diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx index c02aaf4a98..742f034819 100755 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx @@ -565,6 +565,7 @@ class PresentationUploader extends Component { commands[newCurrentIndex] = { $apply: (presentation) => { + if (!presentation) return; const p = presentation; if (p) { p.current = true; diff --git a/bigbluebutton-html5/imports/ui/components/settings/submenus/notification/component.jsx b/bigbluebutton-html5/imports/ui/components/settings/submenus/notification/component.jsx index 1e5fdff941..7166e6694c 100644 --- a/bigbluebutton-html5/imports/ui/components/settings/submenus/notification/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/settings/submenus/notification/component.jsx @@ -20,7 +20,7 @@ const intlMessages = defineMessages({ }, pushAlertLabel: { id: 'app.submenu.notification.pushAlertLabel', - description: 'push notifiation label', + description: 'push notification label', }, messagesLabel: { id: 'app.submenu.notification.messagesLabel', diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/component.tsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/component.tsx index 3c9264573e..f1e388b8b2 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/component.tsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-graphql/user-participants-title/user-options-dropdown/component.tsx @@ -123,7 +123,7 @@ interface RenderModalProps { isOpen: boolean; priority: string; /* Use 'any' if you don't have specific props; - As this props varies in types usage of any is most apropriate */ + As this props varies in types usage of any is most appropriate */ // eslint-disable-next-line @typescript-eslint/no-explicit-any Component: React.ComponentType; otherOptions: object; diff --git a/bigbluebutton-html5/imports/ui/components/video-preview/component.jsx b/bigbluebutton-html5/imports/ui/components/video-preview/component.jsx index 70a5e6077b..d7da1fa6ad 100755 --- a/bigbluebutton-html5/imports/ui/components/video-preview/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/video-preview/component.jsx @@ -309,7 +309,7 @@ class VideoPreview extends Component { const newDevices = await navigator.mediaDevices.enumerateDevices(); webcams = PreviewService.digestVideoDevices(newDevices, webcamDeviceId).webcams; } catch (error) { - // Not a critical error beucase it should only affect UI; log it + // Not a critical error because it should only affect UI; log it // and go ahead logger.error({ logCode: 'video_preview_enumerate_relabel_failure', @@ -1059,7 +1059,7 @@ class VideoPreview extends Component { Chrome, 1: Firefox, diff --git a/bigbluebutton-html5/imports/ui/components/video-preview/service.js b/bigbluebutton-html5/imports/ui/components/video-preview/service.js index b90ed6a2e5..52f0ccdbd4 100755 --- a/bigbluebutton-html5/imports/ui/components/video-preview/service.js +++ b/bigbluebutton-html5/imports/ui/components/video-preview/service.js @@ -200,7 +200,7 @@ const doGUM = (deviceId, profile) => { // Chrome/Edge sometimes bork gUM calls when switching camera // profiles. This looks like a browser bug. Track release not // being done synchronously -> quick subsequent gUM calls for the same - // device (profile switching) -> device becoming unavaible while previous + // device (profile switching) -> device becoming unavailable while previous // tracks aren't finished - prlanzarin if (browserInfo.isChrome || browserInfo.isEdge) { const opts = { diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx b/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx index c25e155818..5d2679f963 100755 --- a/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx @@ -205,7 +205,7 @@ class VideoProvider extends Component { } = this.props; const { socketOpen } = this.state; - // Only debounce when page changes to avoid unecessary debouncing + // Only debounce when page changes to avoid unnecessary debouncing const shouldDebounce = VideoService.isPaginationEnabled() && prevProps.currentVideoPageIndex !== currentVideoPageIndex; @@ -1174,7 +1174,7 @@ class VideoProvider extends Component { peer.started = true; - // Clear camera shared timeout when camera succesfully starts + // Clear camera shared timeout when camera successfully starts this.clearRestartTimers(stream); this.attachVideoStream(stream); diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/service.js b/bigbluebutton-html5/imports/ui/components/video-provider/service.js index 6774bb5f29..606eb8fcbf 100755 --- a/bigbluebutton-html5/imports/ui/components/video-provider/service.js +++ b/bigbluebutton-html5/imports/ui/components/video-provider/service.js @@ -468,7 +468,7 @@ class VideoService { const connectingStream = this.getConnectingStream(streams); if (connectingStream) streams.push(connectingStream); - // Pagination is either explictly disabled or pagination is set to 0 (which + // Pagination is either explicitly disabled or pagination is set to 0 (which // is equivalent to disabling it), so return the mapped streams as they are // which produces the original non paginated behaviour if (isPaginationDisabled) { @@ -900,7 +900,7 @@ class VideoService { parameters.encodings = [{}]; } - // Only reset bitrate if it changed in some way to avoid enconder fluctuations + // Only reset bitrate if it changed in some way to avoid encoder fluctuations if (parameters.encodings[0].maxBitrate !== normalizedBitrate) { parameters.encodings[0].maxBitrate = normalizedBitrate; sender.setParameters(parameters) diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/video-list/component.jsx b/bigbluebutton-html5/imports/ui/components/video-provider/video-list/component.jsx index b05bbfbca0..2ac9c2fc49 100755 --- a/bigbluebutton-html5/imports/ui/components/video-provider/video-list/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/video-provider/video-list/component.jsx @@ -200,7 +200,7 @@ class VideoList extends Component { canvasWidth, canvasHeight, gridGutter, ASPECT_RATIO, numItems, col, ); - // We need a minimun of 2 rows and columns for the focused + // We need a minimum of 2 rows and columns for the focused const focusedConstraint = hasFocusedItem ? testGrid.rows > 1 && testGrid.columns > 1 : true; const betterThanCurrent = testGrid.filledArea > currentGrid.filledArea; return focusedConstraint && betterThanCurrent ? testGrid : currentGrid; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/container.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/container.jsx index 96c351350c..54dfb85437 100644 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/container.jsx @@ -1,14 +1,20 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { + useEffect, + useRef, + useState, + useMemo, +} from 'react'; import { useSubscription, useMutation } from '@apollo/client'; import { AssetRecordType, } from '@tldraw/tldraw'; +import { throttle } from 'radash'; import { CURRENT_PRESENTATION_PAGE_SUBSCRIPTION, CURRENT_PAGE_ANNOTATIONS_STREAM, CURRENT_PAGE_WRITERS_SUBSCRIPTION, + CURSOR_SUBSCRIPTION, } from './queries'; -import { CURSOR_SUBSCRIPTION } from './cursors/queries'; import { initDefaultPages, persistShape, @@ -17,7 +23,6 @@ import { toggleToolsAnimations, formatAnnotations, } from './service'; -import CursorService from './cursors/service'; import SettingsService from '/imports/ui/services/settings'; import Auth from '/imports/ui/services/auth'; import { @@ -35,6 +40,7 @@ import { PRES_ANNOTATION_DELETE, PRES_ANNOTATION_SUBMIT, PRESENTATION_SET_PAGE, + PRESENTATION_PUBLISH_CURSOR, } from '../presentation/mutations'; const WHITEBOARD_CONFIG = window.meetingClientSettings.public.whiteboard; @@ -76,6 +82,7 @@ const WhiteboardContainer = (props) => { const [presentationSetPage] = useMutation(PRESENTATION_SET_PAGE); const [presentationDeleteAnnotations] = useMutation(PRES_ANNOTATION_DELETE); const [presentationSubmitAnnotations] = useMutation(PRES_ANNOTATION_SUBMIT); + const [presentationPublishCursor] = useMutation(PRESENTATION_PUBLISH_CURSOR); const setPresentationPage = (pageId) => { presentationSetPage({ @@ -131,6 +138,23 @@ const WhiteboardContainer = (props) => { persistShape(shape, whiteboardId, isModerator, submitAnnotations); }; + const publishCursorUpdate = (payload) => { + const { whiteboardId, xPercent, yPercent } = payload; + + presentationPublishCursor({ + variables: { + whiteboardId, + xPercent, + yPercent, + }, + }); + }; + + const throttledPublishCursorUpdate = useMemo(() => throttle( + { interval: WHITEBOARD_CONFIG.cursorInterval }, + publishCursorUpdate, + ), []); + const isMultiUserActive = whiteboardWriters?.length > 0; const { data: currentUser } = useCurrentUser((user) => ({ @@ -282,7 +306,7 @@ const WhiteboardContainer = (props) => { }} {...props} meetingId={Auth.meetingID} - publishCursorUpdate={CursorService.publishCursorUpdate} + publishCursorUpdate={throttledPublishCursorUpdate} otherCursors={cursorArray} hideViewersCursor={meeting?.data?.lockSettings?.hideViewersCursor} /> diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/component.jsx deleted file mode 100644 index d85a606be3..0000000000 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/component.jsx +++ /dev/null @@ -1,337 +0,0 @@ -import * as React from 'react'; -import PropTypes from 'prop-types'; -import { Meteor } from 'meteor/meteor'; -import Cursor from './cursor/component'; -import PositionLabel from './position-label/component'; - -const XS_OFFSET = 8; -const SMALL_OFFSET = 18; -const XL_OFFSET = 85; -const BOTTOM_CAM_HANDLE_HEIGHT = 10; -const PRES_TOOLBAR_HEIGHT = 35; - -const baseName = window.meetingClientSettings.public.app.cdn + window.meetingClientSettings.public.app.basename; -const makeCursorUrl = (filename) => `${baseName}/resources/images/whiteboard-cursor/${filename}`; - -const TOOL_CURSORS = { - select: 'default', - erase: 'crosshair', - arrow: 'crosshair', - draw: `url('${makeCursorUrl('pencil.png')}') 2 22, default`, - rectangle: `url('${makeCursorUrl('square.png')}'), default`, - ellipse: `url('${makeCursorUrl('ellipse.png')}'), default`, - triangle: `url('${makeCursorUrl('triangle.png')}'), default`, - line: `url('${makeCursorUrl('line.png')}'), default`, - text: `url('${makeCursorUrl('text.png')}'), default`, - sticky: `url('${makeCursorUrl('square.png')}'), default`, - pan: 'grab', - grabbing: 'grabbing', - moving: 'move', -}; -const Cursors = (props) => { - const cursorWrapper = React.useRef(); - const [active, setActive] = React.useState(false); - const [pos, setPos] = React.useState({ x: 0, y: 0 }); - const { - whiteboardId, - otherCursors, - currentUser, - currentPoint, - tldrawCamera, - publishCursorUpdate, - children, - hasWBAccess, - isMultiUserActive, - isPanning, - isMoving, - currentTool, - toggleToolsAnimations, - whiteboardToolbarAutoHide, - application, - whiteboardWriters, - } = props; - - const [panGrabbing, setPanGrabbing] = React.useState(false); - - const start = (event) => { - const targetElement = event?.target; - const className = targetElement instanceof SVGElement - ? targetElement?.className?.baseVal - : targetElement?.className; - const hasTlPartial = className?.includes('tl-'); - if (hasTlPartial) { - event?.preventDefault(); - } - if (whiteboardToolbarAutoHide) toggleToolsAnimations('fade-out', 'fade-in', application?.animations ? '.3s' : '0s'); - setActive(true); - }; - const handleGrabbing = () => setPanGrabbing(true); - const handleReleaseGrab = () => setPanGrabbing(false); - - const end = () => { - if (whiteboardId && (hasWBAccess || currentUser?.presenter)) { - publishCursorUpdate({ - xPercent: -1.0, - yPercent: -1.0, - whiteboardId, - }); - } - if (whiteboardToolbarAutoHide) toggleToolsAnimations('fade-in', 'fade-out', application?.animations ? '3s' : '0s'); - setActive(false); - }; - - const moved = (event) => { - const { type, x, y } = event; - const nav = document.getElementById('Navbar'); - const getSibling = (el) => { - if (el?.previousSibling && !el?.previousSibling?.hasAttribute('data-test')) { - return el?.previousSibling; - } - return null; - }; - const panel = getSibling(nav); - const webcams = document.getElementById('cameraDock'); - const subPanel = panel && getSibling(panel); - const camPosition = document.getElementById('layout')?.getAttribute('data-cam-position') || null; - const sl = document.getElementById('layout')?.getAttribute('data-layout'); - const presentationContainer = document.querySelector('[data-test="presentationContainer"]'); - const presentation = document.getElementById('currentSlideText')?.parentElement; - const banners = document.querySelectorAll('[data-test="notificationBannerBar"]'); - let yOffset = 0; - let xOffset = 0; - const calcPresOffset = () => { - yOffset - += (parseFloat(presentationContainer?.style?.height) - - (parseFloat(presentation?.style?.height) - + (currentUser.presenter ? PRES_TOOLBAR_HEIGHT : 0)) - ) / 2; - xOffset - += (parseFloat(presentationContainer?.style?.width) - - parseFloat(presentation?.style?.width) - ) / 2; - }; - // If the presentation container is the full screen element we don't - // need any offsets - const { webkitFullscreenElement, fullscreenElement } = document; - const fsEl = webkitFullscreenElement || fullscreenElement; - if (fsEl?.getAttribute('data-test') === 'presentationContainer') { - calcPresOffset(); - return setPos({ x: x - xOffset, y: y - yOffset }); - } - if (nav) yOffset += parseFloat(nav?.style?.height); - if (panel) xOffset += parseFloat(panel?.style?.width); - if (subPanel) xOffset += parseFloat(subPanel?.style?.width); - - // offset native tldraw eraser animation container - const overlay = document.getElementsByClassName('tl-overlay')[0]; - if (overlay) overlay.style.left = '0px'; - - if (type === 'touchmove') { - calcPresOffset(); - if (!active) { - setActive(true); - } - const newX = event?.changedTouches[0]?.clientX - xOffset; - const newY = event?.changedTouches[0]?.clientY - yOffset; - return setPos({ x: newX, y: newY }); - } - - if (document?.documentElement?.dir === 'rtl') { - xOffset = 0; - if (presentationContainer && presentation) { - calcPresOffset(); - } - if (sl.includes('custom')) { - if (webcams) { - if (camPosition === 'contentTop' || !camPosition) { - yOffset += (parseFloat(webcams?.style?.height || 0) + BOTTOM_CAM_HANDLE_HEIGHT); - } - if (camPosition === 'contentBottom') { - yOffset -= BOTTOM_CAM_HANDLE_HEIGHT; - } - if (camPosition === 'contentRight') { - xOffset += (parseFloat(webcams?.style?.width || 0) + SMALL_OFFSET); - } - } - } - if (sl?.includes('smart')) { - if (panel || subPanel) { - const dockPos = webcams?.getAttribute('data-position'); - if (dockPos === 'contentTop') { - yOffset += (parseFloat(webcams?.style?.height || 0) + SMALL_OFFSET); - } - } - } - if (webcams && sl?.includes('videoFocus')) { - xOffset += parseFloat(nav?.style?.width); - yOffset += (parseFloat(panel?.style?.height || 0) - XL_OFFSET); - } - } else { - if (sl.includes('custom')) { - if (webcams) { - if (camPosition === 'contentTop' || !camPosition) { - yOffset += (parseFloat(webcams?.style?.height) || 0) + XS_OFFSET; - } - if (camPosition === 'contentBottom') { - yOffset -= BOTTOM_CAM_HANDLE_HEIGHT; - } - if (camPosition === 'contentLeft') { - xOffset += (parseFloat(webcams?.style?.width) || 0) + SMALL_OFFSET; - } - } - } - - if (sl.includes('smart')) { - if (panel || subPanel) { - const dockPos = webcams?.getAttribute('data-position'); - if (dockPos === 'contentLeft') { - xOffset += (parseFloat(webcams?.style?.width || 0) + SMALL_OFFSET); - } - if (dockPos === 'contentTop') { - yOffset += (parseFloat(webcams?.style?.height || 0) + SMALL_OFFSET); - } - } - if (!panel && !subPanel) { - if (webcams) { - xOffset = parseFloat(webcams?.style?.width || 0) + SMALL_OFFSET; - } - } - } - if (sl?.includes('videoFocus')) { - if (webcams) { - xOffset = parseFloat(subPanel?.style?.width); - yOffset = parseFloat(panel?.style?.height); - } - } - if (presentationContainer && presentation) { - calcPresOffset(); - } - } - - if (banners) { - banners.forEach((el) => { - yOffset += parseFloat(window.getComputedStyle(el).height); - }); - } - - return setPos({ x: event.x - xOffset, y: event.y - yOffset }); - }; - - React.useEffect(() => { - const currentCursor = cursorWrapper?.current; - currentCursor?.addEventListener('mouseenter', start); - currentCursor?.addEventListener('touchstart', start); - currentCursor?.addEventListener('mouseleave', end); - currentCursor?.addEventListener('mousedown', handleGrabbing); - currentCursor?.addEventListener('mouseup', handleReleaseGrab); - currentCursor?.addEventListener('touchend', end); - currentCursor?.addEventListener('mousemove', moved); - currentCursor?.addEventListener('touchmove', moved); - - return () => { - currentCursor?.removeEventListener('mouseenter', start); - currentCursor?.addEventListener('touchstart', start); - currentCursor?.removeEventListener('mouseleave', end); - currentCursor?.removeEventListener('mousedown', handleGrabbing); - currentCursor?.removeEventListener('mouseup', handleReleaseGrab); - currentCursor?.removeEventListener('touchend', end); - currentCursor?.removeEventListener('mousemove', moved); - currentCursor?.removeEventListener('touchmove', moved); - }; - }, [cursorWrapper, whiteboardId, currentUser?.presenter, whiteboardToolbarAutoHide]); - - let cursorType = hasWBAccess || currentUser?.presenter ? TOOL_CURSORS[currentTool] : 'default'; - - if (isPanning) { - if (panGrabbing) { - cursorType = TOOL_CURSORS.grabbing; - } else { - cursorType = TOOL_CURSORS.pan; - } - } - if (isMoving) cursorType = TOOL_CURSORS.moving; - return ( - -

- {((active && hasWBAccess) || (active && currentUser?.presenter)) && ( - - )} - {children} -
- {otherCursors - .filter((c) => c?.xPercent && c.xPercent !== -1.0 && c?.yPercent && c.yPercent !== -1.0) - .map((c) => { - if (c && currentUser?.userId !== c?.userId) { - if (c.user.presenter) { - return ( - - ); - } - - return whiteboardWriters?.some((writer) => writer.userId === c?.userId) - && ( - - ); - } - return null; - })} - - ); -}; - -Cursors.propTypes = { - whiteboardId: PropTypes.string, - otherCursors: PropTypes.arrayOf(PropTypes.shape).isRequired, - currentUser: PropTypes.shape({ - userId: PropTypes.string.isRequired, - presenter: PropTypes.bool.isRequired, - }).isRequired, - currentPoint: PropTypes.arrayOf(PropTypes.number), - tldrawCamera: PropTypes.shape({ - point: PropTypes.arrayOf(PropTypes.number).isRequired, - zoom: PropTypes.number.isRequired, - }), - publishCursorUpdate: PropTypes.func.isRequired, - children: PropTypes.arrayOf(PropTypes.element).isRequired, - isMultiUserActive: PropTypes.bool.isRequired, - isPanning: PropTypes.bool.isRequired, - isMoving: PropTypes.bool.isRequired, - currentTool: PropTypes.string, - toggleToolsAnimations: PropTypes.func.isRequired, -}; - -Cursors.defaultProps = { - whiteboardId: undefined, - currentPoint: undefined, - tldrawCamera: undefined, - currentTool: null, -}; - -export default Cursors; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/container.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/container.jsx deleted file mode 100644 index 2921597f1f..0000000000 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/container.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import { useSubscription } from '@apollo/client'; -import SettingsService from '/imports/ui/services/settings'; -import Cursors from './component'; -import Service from './service'; -import { CURSOR_SUBSCRIPTION } from './queries'; -import { omit } from 'radash'; - -const CursorsContainer = (props) => { - const { data: cursorData } = useSubscription(CURSOR_SUBSCRIPTION); - const { pres_page_cursor: cursorArray } = (cursorData || []); - - if (!cursorData) return null; - - return ( - - ) -}; - -export default CursorsContainer; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/cursor/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/cursor/component.jsx deleted file mode 100644 index 23798ef4ec..0000000000 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/cursor/component.jsx +++ /dev/null @@ -1,93 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Meteor } from 'meteor/meteor'; - -const { pointerDiameter } = window.meetingClientSettings.public.whiteboard; - -const Cursor = (props) => { - const { - name, - color, - x, - y, - currentPoint, - tldrawCamera, - isMultiUserActive, - owner = false, - } = props; - - const z = !owner ? 2 : 1; - let _x = null; - let _y = null; - - if (!currentPoint) { - _x = (x + tldrawCamera?.point[0]) * tldrawCamera?.zoom; - _y = (y + tldrawCamera?.point[1]) * tldrawCamera?.zoom; - } - - const transitionStyle = owner ? { transition: 'left 0.3s ease-out, top 0.3s ease-out' } : {}; - - return ( - <> -
- - {isMultiUserActive && ( -
- {name} -
- )} - - ); -}; - -Cursor.propTypes = { - name: PropTypes.string.isRequired, - color: PropTypes.string.isRequired, - x: PropTypes.number.isRequired, - y: PropTypes.number.isRequired, - currentPoint: PropTypes.arrayOf(PropTypes.number), - tldrawCamera: PropTypes.shape({ - point: PropTypes.arrayOf(PropTypes.number).isRequired, - zoom: PropTypes.number.isRequired, - }), - isMultiUserActive: PropTypes.bool.isRequired, - owner: PropTypes.bool, -}; -Cursor.defaultProps = { - owner: false, - currentPoint: undefined, - tldrawCamera: undefined, -}; - -export default Cursor; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/position-label/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/position-label/component.jsx deleted file mode 100644 index 366875aa69..0000000000 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/position-label/component.jsx +++ /dev/null @@ -1,93 +0,0 @@ -import * as React from 'react'; -import PropTypes from 'prop-types'; -import logger from '/imports/startup/client/logger'; -import Cursor from '../cursor/component'; - -const PositionLabel = (props) => { - const { - currentUser, - currentPoint, - tldrawCamera, - publishCursorUpdate, - whiteboardId, - pos, - isMultiUserActive, - } = props; - - const { name, color, userId } = currentUser; - const { x, y } = pos; - const { zoom, point: tldrawPoint } = tldrawCamera; - - React.useEffect(() => { - try { - const point = [x, y]; - publishCursorUpdate({ - xPercent: - point[0] / zoom - tldrawPoint[0], - yPercent: - point[1] / zoom - tldrawPoint[1], - whiteboardId, - }); - } catch (error) { - logger.error({ - logCode: 'cursor_update__error', - extraInfo: { error }, - }, 'Whiteboard catch error on cursor update'); - } - }, [x, y, zoom, tldrawPoint]); - - // eslint-disable-next-line arrow-body-style - React.useEffect(() => { - return () => { - // Disable cursor on unmount - publishCursorUpdate({ - xPercent: -1.0, - yPercent: -1.0, - whiteboardId, - }); - }; - }, []); - - return ( - <> -
- -
- - ); -}; - -PositionLabel.propTypes = { - currentUser: PropTypes.shape({ - name: PropTypes.string.isRequired, - color: PropTypes.string.isRequired, - userId: PropTypes.string.isRequired, - }).isRequired, - currentPoint: PropTypes.arrayOf(PropTypes.number).isRequired, - tldrawCamera: PropTypes.shape({ - point: PropTypes.arrayOf(PropTypes.number).isRequired, - zoom: PropTypes.number.isRequired, - }).isRequired, - publishCursorUpdate: PropTypes.func.isRequired, - whiteboardId: PropTypes.string, - pos: PropTypes.shape({ - x: PropTypes.number.isRequired, - y: PropTypes.number.isRequired, - }).isRequired, - isMultiUserActive: PropTypes.bool.isRequired, -}; - -PositionLabel.defaultProps = { - whiteboardId: undefined, -}; - -export default PositionLabel; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/queries.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/queries.jsx deleted file mode 100644 index 2027ac8f99..0000000000 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/queries.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import { gql } from '@apollo/client'; - -export const CURSOR_SUBSCRIPTION = gql`subscription CursorSubscription { - pres_page_cursor { - isCurrentPage - lastUpdatedAt - pageId - presentationId - userId - xPercent - yPercent - user { - name - presenter - role - } - } -}`; - -export default CURSOR_SUBSCRIPTION; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/service.js b/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/service.js deleted file mode 100644 index bb1283a568..0000000000 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/service.js +++ /dev/null @@ -1,14 +0,0 @@ -import Auth from '/imports/ui/services/auth'; -import { throttle } from '/imports/utils/throttle'; -import { makeCall } from '/imports/ui/services/api'; - -const { cursorInterval: CURSOR_INTERVAL } = window.meetingClientSettings.public.whiteboard; - -const publishCursorUpdate = throttle( - (payload) => makeCall('publishCursorUpdate', Auth.meetingID, Auth.userID, payload), - CURSOR_INTERVAL, -); - -export default { - publishCursorUpdate, -}; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/hooks.js b/bigbluebutton-html5/imports/ui/components/whiteboard/hooks.js index 58e466baff..40df691662 100644 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/hooks.js +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/hooks.js @@ -13,9 +13,9 @@ const useCursor = (publishCursorUpdate, whiteboardId) => { useEffect(() => { publishCursorUpdate({ + whiteboardId, xPercent: cursorPosition?.x, yPercent: cursorPosition?.y, - whiteboardId, }); }, [cursorPosition, publishCursorUpdate, whiteboardId]); diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/queries.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/queries.jsx index 6a9b02c526..1cb6955ea9 100644 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/queries.jsx +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/queries.jsx @@ -112,4 +112,21 @@ export const CURRENT_PAGE_WRITERS_QUERY = gql`query currentPageWritersQuery { } }`; +export const CURSOR_SUBSCRIPTION = gql`subscription CursorSubscription { + pres_page_cursor { + isCurrentPage + lastUpdatedAt + pageId + presentationId + userId + xPercent + yPercent + user { + name + presenter + role + } + } +}`; + export default CURRENT_PAGE_ANNOTATIONS_QUERY; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/service.js b/bigbluebutton-html5/imports/ui/components/whiteboard/service.js index b2219bd14c..ea5c8f521a 100755 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/service.js +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/service.js @@ -287,4 +287,4 @@ export { notifyShapeNumberExceeded, toggleToolsAnimations, formatAnnotations, -}; \ No newline at end of file +}; diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/styles.js b/bigbluebutton-html5/imports/ui/components/whiteboard/styles.js index ebaf5ca4cb..931c8616e2 100644 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/styles.js +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/styles.js @@ -62,7 +62,7 @@ const TldrawV2GlobalStyle = createGlobalStyle` .tlui-navigation-zone, .tlui-help-menu, .tlui-debug-panel { - display: none; + display: none !important; } .tlui-style-panel__wrapper { @@ -93,8 +93,8 @@ const TldrawV2GlobalStyle = createGlobalStyle` [data-testid="main.menu"], [data-testid="tools.laser"], [data-testid="tools.asset"], - .tlui-menu-zone__controls > :nth-child(1), - .tlui-menu-zone__controls > :nth-child(2) { + .tlui-buttons__horizontal > :nth-child(1), + .tlui-buttons__horizontal > :nth-child(2) { display: none; } diff --git a/bigbluebutton-html5/imports/ui/services/LocalCollectionSynchronizer/LocalCollectionSynchronizer.js b/bigbluebutton-html5/imports/ui/services/LocalCollectionSynchronizer/LocalCollectionSynchronizer.js index 92684d0f62..5f76300ae4 100644 --- a/bigbluebutton-html5/imports/ui/services/LocalCollectionSynchronizer/LocalCollectionSynchronizer.js +++ b/bigbluebutton-html5/imports/ui/services/LocalCollectionSynchronizer/LocalCollectionSynchronizer.js @@ -108,7 +108,7 @@ class LocalCollectionSynchronizer { const subscription = SubscriptionRegistry.getSubscription(this.serverCollection._name); // If the subscriptionId changes means the subscriptions was redone - // or theres more than one subscription per collection + // or there's more than one subscription per collection if (subscription && (this.lastSubscriptionId !== subscription.subscriptionId)) { const wasEmpty = this.lastSubscriptionId === ''; this.lastSubscriptionId = subscription.subscriptionId; diff --git a/bigbluebutton-html5/imports/ui/services/api/index.js b/bigbluebutton-html5/imports/ui/services/api/index.js index ee510dafbc..1a8a34871a 100755 --- a/bigbluebutton-html5/imports/ui/services/api/index.js +++ b/bigbluebutton-html5/imports/ui/services/api/index.js @@ -18,7 +18,7 @@ export function makeCall(name, ...args) { return new Promise(async (resolve, reject) => { if (Meteor.status().connected) { const result = await Meteor.callAsync(name, ...args); - // all tested cases it returnd 0, empty array or undefined + // all tested cases it returned 0, empty array or undefined resolve(result); } else { const failureString = `Call to ${name} failed because Meteor is not connected`; diff --git a/bigbluebutton-html5/imports/ui/services/locale/index.js b/bigbluebutton-html5/imports/ui/services/locale/index.js index 9d82c6a9c7..3da96e2f31 100644 --- a/bigbluebutton-html5/imports/ui/services/locale/index.js +++ b/bigbluebutton-html5/imports/ui/services/locale/index.js @@ -3,7 +3,7 @@ import { createIntl } from 'react-intl'; const FALLBACK_ON_EMPTY_STRING = window.meetingClientSettings.public.app.fallbackOnEmptyLocaleString; /** - * Use this if you need any translation outside of React lifecyle. + * Use this if you need any translation outside of React lifecycle. */ class BBBIntl { _intl = { diff --git a/bigbluebutton-html5/imports/ui/services/storage/reactive.js b/bigbluebutton-html5/imports/ui/services/storage/reactive.js index 01ca7ecd67..ad2e3ab7df 100755 --- a/bigbluebutton-html5/imports/ui/services/storage/reactive.js +++ b/bigbluebutton-html5/imports/ui/services/storage/reactive.js @@ -7,7 +7,7 @@ import { isObject, isArray, isString } from 'radash'; export default class StorageTracker { constructor(storage, prefix = '') { if (!(storage instanceof Storage)) { - throw `Expecting a instanceof Storage recieve a '${storage.constructor.name}' instance`; + throw `Expecting a instanceof Storage receive a '${storage.constructor.name}' instance`; } this._trackers = {}; diff --git a/bigbluebutton-html5/imports/ui/services/webrtc-base/peer.js b/bigbluebutton-html5/imports/ui/services/webrtc-base/peer.js index 133d7046a3..30d6f80410 100644 --- a/bigbluebutton-html5/imports/ui/services/webrtc-base/peer.js +++ b/bigbluebutton-html5/imports/ui/services/webrtc-base/peer.js @@ -185,7 +185,7 @@ export default class WebRtcPeer extends EventEmitter2 { return this.peerConnection.setLocalDescription(rtcSessionDescription); } - // Public method can be overriden via options + // Public method can be overridden via options mediaStreamFactory() { if (this.videoStream || this.audioStream) { return Promise.resolve(); diff --git a/bigbluebutton-html5/imports/utils/regex-weburl.js b/bigbluebutton-html5/imports/utils/regex-weburl.js index 575f0134ca..028a347872 100644 --- a/bigbluebutton-html5/imports/utils/regex-weburl.js +++ b/bigbluebutton-html5/imports/utils/regex-weburl.js @@ -92,7 +92,7 @@ export default new RegExp( // IP address dotted notation octets // excludes loopback network 0.0.0.0 // excludes reserved space >= 224.0.0.0 - // excludes network & broacast addresses + // excludes network & broadcast addresses // (first & last IP address of each class) '(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])' + '(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}' + diff --git a/bigbluebutton-html5/imports/utils/slideCalcUtils.js b/bigbluebutton-html5/imports/utils/slideCalcUtils.js index 354c6169f6..5018d6fc59 100755 --- a/bigbluebutton-html5/imports/utils/slideCalcUtils.js +++ b/bigbluebutton-html5/imports/utils/slideCalcUtils.js @@ -4,7 +4,7 @@ export const MYSTERY_NUM = 2; export const STEP = 25; export default class SlideCalcUtil { - // After lots of trial and error on why synching doesn't work properly, I found I had to + // After lots of trial and error on why syncing doesn't work properly, I found I had to // multiply the coordinates by 2. There's something I don't understand probably on the // canvas coordinate system. (ralam feb 22, 2012) diff --git a/bigbluebutton-html5/package-lock.json b/bigbluebutton-html5/package-lock.json index 566c062ecf..aa44887b5f 100644 --- a/bigbluebutton-html5/package-lock.json +++ b/bigbluebutton-html5/package-lock.json @@ -1,7 +1,7 @@ { "name": "bbb-html5-client", - "requires": true, "lockfileVersion": 1, + "requires": true, "dependencies": { "@aashutoshrathi/word-wrap": { "version": "1.2.6", @@ -4066,13 +4066,13 @@ } }, "dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" } }, "domelementtype": { @@ -4081,21 +4081,21 @@ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" }, "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "requires": { - "domelementtype": "^2.2.0" + "domelementtype": "^2.3.0" } }, "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" } }, "electron-to-chromium": { @@ -4139,9 +4139,9 @@ } }, "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, "error-ex": { "version": "1.3.2", @@ -5231,14 +5231,14 @@ "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==" }, "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" } }, "human-signals": { @@ -6143,6 +6143,7 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "bundled": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", @@ -6153,7 +6154,8 @@ "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "bundled": true } } }, @@ -6161,6 +6163,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "bundled": true, "requires": { "es6-object-assign": "^1.1.0", "is-nan": "^1.2.1", @@ -6171,27 +6174,32 @@ "available-typed-arrays": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", - "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==" + "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==", + "bundled": true }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "bundled": true }, "bn.js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "bundled": true }, "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "bundled": true }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "bundled": true, "requires": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -6205,6 +6213,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "bundled": true, "requires": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", @@ -6215,6 +6224,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "bundled": true, "requires": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", @@ -6226,6 +6236,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "bundled": true, "requires": { "bn.js": "^5.0.0", "randombytes": "^2.0.1" @@ -6235,6 +6246,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "bundled": true, "requires": { "bn.js": "^5.1.1", "browserify-rsa": "^4.0.1", @@ -6251,6 +6263,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "bundled": true, "requires": { "pako": "~1.0.5" } @@ -6259,6 +6272,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "bundled": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -6267,17 +6281,20 @@ "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "bundled": true }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "bundled": true }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "bundled": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -6287,6 +6304,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "bundled": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -6295,17 +6313,20 @@ "console-browserify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "bundled": true }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "bundled": true }, "create-ecdh": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "bundled": true, "requires": { "bn.js": "^4.1.0", "elliptic": "^6.5.3" @@ -6314,7 +6335,8 @@ "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "bundled": true } } }, @@ -6322,6 +6344,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "bundled": true, "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -6334,6 +6357,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "bundled": true, "requires": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -6347,6 +6371,7 @@ "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "bundled": true, "requires": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", @@ -6365,6 +6390,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "bundled": true, "requires": { "object-keys": "^1.0.12" } @@ -6373,6 +6399,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "bundled": true, "requires": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" @@ -6382,6 +6409,7 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "bundled": true, "requires": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", @@ -6391,19 +6419,22 @@ "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "bundled": true } } }, "domain-browser": { "version": "4.22.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", - "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==" + "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", + "bundled": true }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "bundled": true, "requires": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -6417,7 +6448,8 @@ "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "bundled": true } } }, @@ -6425,6 +6457,7 @@ "version": "1.18.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "bundled": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", @@ -6448,6 +6481,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "bundled": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -6457,17 +6491,20 @@ "es6-object-assign": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=", + "bundled": true }, "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "bundled": true }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "bundled": true, "requires": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -6476,17 +6513,20 @@ "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "bundled": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "bundled": true }, "get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "bundled": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -6497,6 +6537,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "bundled": true, "requires": { "function-bind": "^1.1.1" } @@ -6504,17 +6545,20 @@ "has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "bundled": true }, "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "bundled": true }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "bundled": true, "requires": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -6525,6 +6569,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "bundled": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -6534,6 +6579,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "bundled": true, "requires": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -6543,22 +6589,26 @@ "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "bundled": true }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "bundled": true }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "bundled": true }, "is-arguments": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "bundled": true, "requires": { "call-bind": "^1.0.0" } @@ -6566,12 +6616,14 @@ "is-bigint": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "bundled": true }, "is-boolean-object": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "bundled": true, "requires": { "call-bind": "^1.0.2" } @@ -6579,22 +6631,26 @@ "is-callable": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "bundled": true }, "is-date-object": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "bundled": true }, "is-generator-function": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", - "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==" + "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==", + "bundled": true }, "is-nan": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "bundled": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -6603,17 +6659,20 @@ "is-negative-zero": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "bundled": true }, "is-number-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==" + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "bundled": true }, "is-regex": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "bundled": true, "requires": { "call-bind": "^1.0.2", "has-symbols": "^1.0.2" @@ -6622,12 +6681,14 @@ "is-string": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "bundled": true }, "is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "bundled": true, "requires": { "has-symbols": "^1.0.2" } @@ -6636,6 +6697,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", + "bundled": true, "requires": { "available-typed-arrays": "^1.0.2", "call-bind": "^1.0.2", @@ -6648,6 +6710,7 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "bundled": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -6658,6 +6721,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "bundled": true, "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" @@ -6666,29 +6730,34 @@ "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "bundled": true } } }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "bundled": true }, "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "bundled": true }, "object-inspect": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "bundled": true }, "object-is": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "bundled": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -6697,12 +6766,14 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "bundled": true }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "bundled": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -6713,17 +6784,20 @@ "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "bundled": true }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "bundled": true }, "parse-asn1": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "bundled": true, "requires": { "asn1.js": "^5.2.0", "browserify-aes": "^1.0.0", @@ -6735,12 +6809,14 @@ "path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "bundled": true }, "pbkdf2": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "bundled": true, "requires": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -6752,12 +6828,14 @@ "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "bundled": true }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "bundled": true, "requires": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", @@ -6770,29 +6848,34 @@ "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "bundled": true } } }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "bundled": true }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "bundled": true }, "querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "bundled": true }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "bundled": true, "requires": { "safe-buffer": "^5.1.0" } @@ -6801,6 +6884,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "bundled": true, "requires": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" @@ -6810,6 +6894,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "bundled": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -6820,6 +6905,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "bundled": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -6828,22 +6914,26 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "bundled": true }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "bundled": true }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "bundled": true }, "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "bundled": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -6853,6 +6943,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "bundled": true, "requires": { "inherits": "~2.0.4", "readable-stream": "^3.5.0" @@ -6862,6 +6953,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "bundled": true, "requires": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.4", @@ -6869,10 +6961,20 @@ "xtend": "^4.0.2" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "bundled": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string.prototype.trimend": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "bundled": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -6882,23 +6984,17 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "bundled": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "timers-browserify": { "version": "2.0.12", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "bundled": true, "requires": { "setimmediate": "^1.0.4" } @@ -6906,12 +7002,14 @@ "tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==" + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "bundled": true }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "bundled": true, "requires": { "function-bind": "^1.1.1", "has-bigints": "^1.0.1", @@ -6923,6 +7021,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "bundled": true, "requires": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -6931,7 +7030,8 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "bundled": true } } }, @@ -6939,6 +7039,7 @@ "version": "0.12.4", "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "bundled": true, "requires": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -6951,17 +7052,20 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "bundled": true }, "which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "bundled": true, "requires": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -6974,6 +7078,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", + "bundled": true, "requires": { "available-typed-arrays": "^1.0.2", "call-bind": "^1.0.0", @@ -6987,7 +7092,8 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "bundled": true } } }, @@ -8437,13 +8543,13 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sanitize-html": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.7.1.tgz", - "integrity": "sha512-oOpe8l4J8CaBk++2haoN5yNI5beekjuHv3JRPKUx/7h40Rdr85pemn4NkvUB3TcBP7yjat574sPlcMAyv4UQig==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.12.1.tgz", + "integrity": "sha512-Plh+JAn0UVDpBRP/xEjsk+xDCoOvMBwQUf/K+/cBAVuTbtX8bj2VB7S1sL1dssVpykqp0/KPSesHrqXtokVBpA==", "requires": { "deepmerge": "^4.2.2", "escape-string-regexp": "^4.0.0", - "htmlparser2": "^6.0.0", + "htmlparser2": "^8.0.0", "is-plain-object": "^5.0.0", "parse-srcset": "^1.0.2", "postcss": "^8.3.11" @@ -8738,6 +8844,14 @@ "resolved": "https://registry.npmjs.org/strictdom/-/strictdom-1.0.1.tgz", "integrity": "sha512-cEmp9QeXXRmjj/rVp9oyiqcvyocWab/HaoN4+bwFeZ7QzykJD6L3yD4v12K1x0tHpqRqVpJevN3gW7kyM39Bqg==" }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", @@ -8810,14 +8924,6 @@ "es-abstract": "^1.22.1" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", diff --git a/bigbluebutton-html5/package.json b/bigbluebutton-html5/package.json index d816433e0d..1ac9ba8130 100644 --- a/bigbluebutton-html5/package.json +++ b/bigbluebutton-html5/package.json @@ -96,7 +96,7 @@ "recharts": "^2.7.2", "reconnecting-websocket": "~v4.4.0", "redis": "^3.1.2", - "sanitize-html": "2.7.1", + "sanitize-html": "2.12.1", "scheduler": "^0.20.2", "sdp-transform": "2.7.0", "smile2emoji": "^3.8.3", diff --git a/bigbluebutton-html5/private/config/settings.yml b/bigbluebutton-html5/private/config/settings.yml index 915997198e..d91f4f70ed 100755 --- a/bigbluebutton-html5/private/config/settings.yml +++ b/bigbluebutton-html5/private/config/settings.yml @@ -162,11 +162,11 @@ public: # emojiSize: size of the emoji in 'em' units emojiSize: 2 # If enabled, before joining microphone the client will perform a trickle - # ICE against Kurento and use the information about successfull + # ICE against Kurento and use the information about successful # candidate-pairs to filter out local candidates in SIP.js's SDP. # Try enabling this setting in scenarios where the listenonly mode works, # but microphone doesn't (for example, when using VPN). - # For compatibility check "Browser compatbility" section in: + # For compatibility check "Browser compatibility" section in: # https://developer.mozilla.org/en-US/docs/Web/API/RTCDtlsTransport/iceTransport # This is an EXPERIMENTAL setting and the default value is false # experimentalUseKmsTrickleIceForMicrophone: false @@ -216,7 +216,7 @@ public: overrideLocale: null #Audio constraints for microphone. Use this to control browser's #filters, such as AGC (Auto Gain Control) , Echo Cancellation, - #Noise Supression, etc. + #Noise Suppression, etc. #For more deails, see: # https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints #Currently, google chrome sets {ideal: true} for autoGainControl, diff --git a/bigbluebutton-html5/public/compatibility/sip.js b/bigbluebutton-html5/public/compatibility/sip.js index 9f67d80458..6b8d70723c 100644 --- a/bigbluebutton-html5/public/compatibility/sip.js +++ b/bigbluebutton-html5/public/compatibility/sip.js @@ -5422,7 +5422,7 @@ class SessionDialog extends _dialog__WEBPACK_IMPORTED_MODULE_18__["Dialog"] { msg += " but the following tip is provided for avoiding race conditions of"; msg += " this type. The caller can delay sending re-INVITE F6 for some period"; msg += " of time (2 seconds, perhaps), after which the caller can reasonably"; - msg += " assume that its ACK has been received. Implementors can decouple the"; + msg += " assume that its ACK has been received. Implementers can decouple the"; msg += " actions of the user (e.g., pressing the hold button) from the actions"; msg += " of the protocol (the sending of re-INVITE F6), so that the UA can"; msg += " behave like this. In this case, it is the implementor's choice as to"; @@ -5430,7 +5430,7 @@ class SessionDialog extends _dialog__WEBPACK_IMPORTED_MODULE_18__["Dialog"] { msg += " useful to prevent the type of race condition shown in this section."; msg += " This document expresses no preference about whether or not they"; msg += " should wait for an ACK to be delivered. After considering the impact"; - msg += " on user experience, implementors should decide whether or not to wait"; + msg += " on user experience, implementers should decide whether or not to wait"; msg += " for a while, because the user experience depends on the"; msg += " implementation and has no direct bearing on protocol behavior."; this.logger.warn(msg); @@ -11684,7 +11684,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); /** - * An exception indicating a session description handler error occured. + * An exception indicating a session description handler error occurred. * @public */ class SessionDescriptionHandlerError extends _core__WEBPACK_IMPORTED_MODULE_0__["Exception"] { @@ -11724,7 +11724,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); /** - * An exception indicating an invalid state transition error occured. + * An exception indicating an invalid state transition error occurred. * @public */ class StateTransitionError extends _core__WEBPACK_IMPORTED_MODULE_0__["Exception"] { @@ -12297,7 +12297,7 @@ class Invitation extends _session__WEBPACK_IMPORTED_MODULE_3__["Session"] { // State should never be reached as first reliable provisional response must have answer/offer. throw new Error(`Invalid signaling state ${this.dialog.signalingState}.`); case _core__WEBPACK_IMPORTED_MODULE_0__["SignalingState"].Stable: - // Receved answer. + // Received answer. return this.setAnswer(body, options).then(() => undefined); case _core__WEBPACK_IMPORTED_MODULE_0__["SignalingState"].HaveLocalOffer: // State should never be reached as local offer would be answered by this PRACK @@ -14937,7 +14937,7 @@ class Inviter extends _session__WEBPACK_IMPORTED_MODULE_2__["Session"] { if (this.earlyMediaDialog !== session) { if (this.earlyMedia) { const message = "You have set the 'earlyMedia' option to 'true' which requires that your INVITE requests " + - "do not fork and yet this INVITE request did in fact fork. Consequentially and not surprisingly " + + "do not fork and yet this INVITE request did in fact fork. Consequently and not surprisingly " + "the end point which accepted the INVITE (confirmed dialog) does not match the end point with " + "which early media has been setup (early dialog) and thus this session is unable to proceed. " + "In accordance with the SIP specifications, the SIP servers your end point is connected to " + @@ -17817,7 +17817,7 @@ class UserAgent { }, onRefer: (incomingReferRequest) => { this.logger.warn("Received an out of dialog REFER request"); - // TOOD: this.delegate.onRefer(...) + // TODO: this.delegate.onRefer(...) if (this.delegate && this.delegate.onReferRequest) { this.delegate.onReferRequest(incomingReferRequest); } @@ -17827,7 +17827,7 @@ class UserAgent { }, onRegister: (incomingRegisterRequest) => { this.logger.warn("Received an out of dialog REGISTER request"); - // TOOD: this.delegate.onRegister(...) + // TODO: this.delegate.onRegister(...) if (this.delegate && this.delegate.onRegisterRequest) { this.delegate.onRegisterRequest(incomingRegisterRequest); } @@ -17837,7 +17837,7 @@ class UserAgent { }, onSubscribe: (incomingSubscribeRequest) => { this.logger.warn("Received an out of dialog SUBSCRIBE request"); - // TOOD: this.delegate.onSubscribe(...) + // TODO: this.delegate.onSubscribe(...) if (this.delegate && this.delegate.onSubscribeRequest) { this.delegate.onSubscribeRequest(incomingSubscribeRequest); } @@ -19501,7 +19501,7 @@ class Transport { return this.send("\r\n\r\n"); } /** - * Start sending keep-alives. + * Start sending keep-alive. */ startSendingKeepAlives() { // Compute an amount of time in seconds to wait before sending another keep-alive. @@ -19517,7 +19517,7 @@ class Transport { } } /** - * Stop sending keep-alives. + * Stop sending keep-alive. */ stopSendingKeepAlives() { if (this.keepAliveInterval) { @@ -20637,7 +20637,7 @@ class SimpleUser { if (mediaElement) { const localStream = this.localMediaStream; if (!localStream) { - throw new Error("Local media stream undefiend."); + throw new Error("Local media stream undefined."); } mediaElement.srcObject = localStream; mediaElement.volume = 0; @@ -20657,7 +20657,7 @@ class SimpleUser { if (mediaElement) { const remoteStream = this.remoteMediaStream; if (!remoteStream) { - throw new Error("Remote media stream undefiend."); + throw new Error("Remote media stream undefined."); } mediaElement.autoplay = true; // Safari hack, because you cannot call .play() from a non user action mediaElement.srcObject = remoteStream; @@ -20667,7 +20667,7 @@ class SimpleUser { }); remoteStream.onaddtrack = () => { this.logger.log(`[${this.id}] Remote media onaddtrack`); - mediaElement.load(); // Safari hack, as it doesn't work otheriwse + mediaElement.load(); // Safari hack, as it doesn't work otherwise mediaElement.play().catch((error) => { this.logger.error(`[${this.id}] Failed to play remote media`); this.logger.error(error.message); diff --git a/bigbluebutton-html5/server/main.js b/bigbluebutton-html5/server/main.js index e7d39f0c2f..d7539b4cc1 100755 --- a/bigbluebutton-html5/server/main.js +++ b/bigbluebutton-html5/server/main.js @@ -3,7 +3,6 @@ import '/imports/startup/server'; // 2x import '/imports/api/meetings/server'; import '/imports/api/users/server'; -import '/imports/api/cursor/server'; import '/imports/api/polls/server'; import '/imports/api/captions/server'; import '/imports/api/presentation-upload-token/server'; diff --git a/bigbluebutton-tests/gns3/README.md b/bigbluebutton-tests/gns3/README.md index 5e22a948e3..f0f0c34434 100644 --- a/bigbluebutton-tests/gns3/README.md +++ b/bigbluebutton-tests/gns3/README.md @@ -17,7 +17,7 @@ The script will build a gns3 project that looks like this: ![network diagram](README.png) -The network "highjacks" the 128.8.8.0/24 subnet, so it simulates public IP address space. You can set a different public subnet using the `--public-subnet` option to the script. +The network "hijacks" the 128.8.8.0/24 subnet, so it simulates public IP address space. You can set a different public subnet using the `--public-subnet` option to the script. The DNS domain name is configured to match the bare metal hostname. If the bare metal machine is called `osito`, for example, the virtual machines will be given names like `BigBlueButton.osito` and `focal-260.osito`. diff --git a/bigbluebutton-tests/playwright/.env.template b/bigbluebutton-tests/playwright/.env.template index ce22bed4f6..80154d334a 100644 --- a/bigbluebutton-tests/playwright/.env.template +++ b/bigbluebutton-tests/playwright/.env.template @@ -1,5 +1,6 @@ # meeting credentials BBB_URL="" # https://DOMAIN_NAME/bigbluebutton/api BBB_SECRET="" +CHECKSUM="" # (sha1 | sha256 | sha512) Force a specific checksum algorithm. Useful for when the secret length is not a sha algorithm length TIMEOUT_MULTIPLIER=1 # (number / empty) Apply a multiplier on default timeouts - depending the server strength (not recommended to use greater values than 3) diff --git a/bigbluebutton-tests/playwright/core/helpers.js b/bigbluebutton-tests/playwright/core/helpers.js index 4cff6d8039..6fe81b1ec5 100644 --- a/bigbluebutton-tests/playwright/core/helpers.js +++ b/bigbluebutton-tests/playwright/core/helpers.js @@ -1,5 +1,5 @@ require('dotenv').config(); -const sha1 = require('sha1'); +const sha = require('sha.js'); const axios = require('axios'); const { test, expect } = require('@playwright/test'); const xml2js = require('xml2js'); @@ -11,6 +11,24 @@ const { format } = require('node:util'); const chalk = require('chalk'); const parameters = require('./parameters'); +function getChecksum(text, secret) { + let algorithm = (process.env.CHECKSUM || '').toLowerCase(); + if (!['sha1', 'sha256', 'sha512'].includes(algorithm)) { + switch (secret.length) { + case 128: + algorithm = 'sha512'; + break; + case 64: + algorithm = 'sha256'; + break; + case 40: + default: + algorithm = 'sha1' + } + } + return sha(algorithm).update(text).digest('hex'); +} + function getRandomInt(min, max) { min = Math.ceil(min); max = Math.floor(max); @@ -20,7 +38,7 @@ function getRandomInt(min, max) { function apiCallUrl(name, callParams) { const query = new URLSearchParams(callParams).toString(); const apiCall = `${name}${query}${parameters.secret}`; - const checksum = sha1(apiCall); + const checksum = getChecksum(apiCall, parameters.secret); const url = `${parameters.server}/${name}?${query}&checksum=${checksum}`; return url; } @@ -38,7 +56,7 @@ function createMeetingUrl(params, createParameter, customMeetingId) { + `&allowStartStopRecording=true&autoStartRecording=false&welcome=${params.welcome}`; const query = createParameter !== undefined ? `${baseQuery}&${createParameter}` : baseQuery; const apiCall = `create${query}${params.secret}`; - const checksum = sha1(apiCall); + const checksum = getChecksum(apiCall, parameters.secret); const url = `${params.server}/create?${query}&checksum=${checksum}`; return url; } @@ -61,7 +79,7 @@ function getJoinURL(meetingID, params, moderator, joinParameter) { const baseQuery = `fullName=${params.fullName}&meetingID=${meetingID}&password=${pw}`; const query = joinParameter !== undefined ? `${baseQuery}&${joinParameter}` : baseQuery; const apiCall = `join${query}${params.secret}`; - const checksum = sha1(apiCall); + const checksum = getChecksum(apiCall, parameters.secret); return `${params.server}/join?${query}&checksum=${checksum}`; } diff --git a/bigbluebutton-tests/playwright/core/scripts/rewrite-snapshots.sh b/bigbluebutton-tests/playwright/core/scripts/rewrite-snapshots.sh index f564cda090..1f6f8fbadb 100644 --- a/bigbluebutton-tests/playwright/core/scripts/rewrite-snapshots.sh +++ b/bigbluebutton-tests/playwright/core/scripts/rewrite-snapshots.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Save string of folders containg reference snapshots files +# Save string of folders containing reference snapshots files folders_string=$(find . -type d -name "*js-snapshots" -printf "%h\n" | sort | uniq | tr -d './' | tr '\n' ' ') # Find folders diff --git a/bigbluebutton-tests/playwright/package-lock.json b/bigbluebutton-tests/playwright/package-lock.json index 4be69edbda..a86dbd73b5 100644 --- a/bigbluebutton-tests/playwright/package-lock.json +++ b/bigbluebutton-tests/playwright/package-lock.json @@ -1,5 +1,5 @@ { - "name": "npm-proj-1698479958167-0.6855583501888978fQhG4i", + "name": "playwright", "lockfileVersion": 2, "requires": true, "packages": { @@ -11,7 +11,7 @@ "deep-equal": "^2.2.1", "dotenv": "^16.1.4", "playwright": "^1.37.1", - "sha1": "^1.1.1", + "sha.js": "^2.4.11", "xml2js": "^0.6.0" } }, @@ -117,14 +117,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "engines": { - "node": "*" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -152,14 +144,6 @@ "node": ">= 0.8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "engines": { - "node": "*" - } - }, "node_modules/deep-equal": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz", @@ -393,6 +377,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -726,21 +715,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, - "node_modules/sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dependencies": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" }, - "engines": { - "node": "*" + "bin": { + "sha.js": "bin.js" } }, "node_modules/side-channel": { @@ -918,11 +926,6 @@ "supports-color": "^7.1.0" } }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -944,11 +947,6 @@ "delayed-stream": "~1.0.0" } }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" - }, "deep-equal": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz", @@ -1105,6 +1103,11 @@ "has-symbols": "^1.0.2" } }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -1317,18 +1320,23 @@ "functions-have-names": "^1.2.3" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, - "sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "side-channel": { diff --git a/bigbluebutton-tests/playwright/package.json b/bigbluebutton-tests/playwright/package.json index 512348148d..4f9cfafde7 100644 --- a/bigbluebutton-tests/playwright/package.json +++ b/bigbluebutton-tests/playwright/package.json @@ -16,7 +16,7 @@ "deep-equal": "^2.2.1", "dotenv": "^16.1.4", "playwright": "^1.37.1", - "sha1": "^1.1.1", + "sha.js": "^2.4.11", "xml2js": "^0.6.0" } -} \ No newline at end of file +} diff --git a/bigbluebutton-tests/puppeteer/jest.setup.js b/bigbluebutton-tests/puppeteer/jest.setup.js index 660d591e9c..9d1b22b742 100644 --- a/bigbluebutton-tests/puppeteer/jest.setup.js +++ b/bigbluebutton-tests/puppeteer/jest.setup.js @@ -1,2 +1,2 @@ -// 30 min is a little high, this can be tunned down after we get the regular puppeteer runtime +// 30 min is a little high, this can be tuned down after we get the regular puppeteer runtime jest.setTimeout(1800000); diff --git a/bigbluebutton-tests/puppeteer/whiteboard/whiteboard.obj.js b/bigbluebutton-tests/puppeteer/whiteboard/whiteboard.obj.js index ff4d19822e..634198354e 100644 --- a/bigbluebutton-tests/puppeteer/whiteboard/whiteboard.obj.js +++ b/bigbluebutton-tests/puppeteer/whiteboard/whiteboard.obj.js @@ -12,7 +12,7 @@ const whiteboardTest = () => { jest.setTimeout(MAX_WHITEBOARD_TEST_TIMEOUT); }); - // Draw a rectange in whiteboard + // Draw a rectangle in whiteboard // and expect difference in shapes before and after drawing test('Draw rectangle', async () => { const test = new Draw(); diff --git a/bigbluebutton-web/build.gradle b/bigbluebutton-web/build.gradle index c4b782d0f5..361c112fd5 100755 --- a/bigbluebutton-web/build.gradle +++ b/bigbluebutton-web/build.gradle @@ -96,7 +96,7 @@ dependencies { implementation "io.projectreactor:reactor-core:3.4.12" implementation "org.freemarker:freemarker:2.3.31" implementation "com.google.code.gson:gson:2.8.9" - implementation "org.json:json:20230227" + implementation "org.json:json:20231013" implementation "com.zaxxer:nuprocess:2.0.6" implementation "net.java.dev.jna:jna:5.10.0" implementation "org.springframework.data:spring-data-commons:2.7.6" diff --git a/bigbluebutton-web/gradle.properties b/bigbluebutton-web/gradle.properties index 0baceadce8..f2bb1e2631 100644 --- a/bigbluebutton-web/gradle.properties +++ b/bigbluebutton-web/gradle.properties @@ -3,5 +3,5 @@ gormVersion=7.3.1 gradleWrapperVersion=7.6.3 grailsGradlePluginVersion=6.1.0 groovyVersion=3.0.19 -tomcatEmbedVersion=9.0.82 -springVersion=2.7.17 \ No newline at end of file +tomcatEmbedVersion=9.0.86 +springVersion=2.7.17 diff --git a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties index 7e582d4049..f5a8b6dc2b 100644 --- a/bigbluebutton-web/grails-app/conf/bigbluebutton.properties +++ b/bigbluebutton-web/grails-app/conf/bigbluebutton.properties @@ -17,7 +17,7 @@ # # -# These are the default properites for BigBlueButton Web application +# These are the default properties for BigBlueButton Web application # Default loglevel. appLogLevel=DEBUG @@ -260,11 +260,11 @@ maxPinnedCameras=3 muteOnStart=false # Unmute users -# Gives moderators permisson to unmute other users +# Gives moderators permission to unmute other users allowModsToUnmuteUsers=false # Eject user webcams -# Gives moderators permisson to close other users' webcams +# Gives moderators permission to close other users' webcams allowModsToEjectCameras=false # Saves meeting events even if the meeting is not recorded diff --git a/bigbluebutton-web/grailsw.bat b/bigbluebutton-web/grailsw.bat index c48c384063..8508a03283 100755 --- a/bigbluebutton-web/grailsw.bat +++ b/bigbluebutton-web/grailsw.bat @@ -46,7 +46,7 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args diff --git a/bigbluebutton-web/src/main/webapp/WEB-INF/tld/c.tld b/bigbluebutton-web/src/main/webapp/WEB-INF/tld/c.tld index 5e18236fef..00146d8d70 100755 --- a/bigbluebutton-web/src/main/webapp/WEB-INF/tld/c.tld +++ b/bigbluebutton-web/src/main/webapp/WEB-INF/tld/c.tld @@ -53,7 +53,7 @@ scoped variable is the type of the exception thrown. - Simple conditional tag, which evalutes its body if the + Simple conditional tag, which evaluates its body if the supplied condition is true and optionally exposes a Boolean scripting variable representing the evaluation of this condition @@ -243,7 +243,7 @@ visibility. - Iterates over tokens, separated by the supplied delimeters + Iterates over tokens, separated by the supplied delimiters forTokens org.apache.taglibs.standard.tag.rt.core.ForTokensTag @@ -552,7 +552,7 @@ resource that belongs to a foreign context. Subtag of <choose> that includes its body if its - condition evalutes to 'true' + condition evaluates to 'true' when org.apache.taglibs.standard.tag.rt.core.WhenTag diff --git a/bigbluebutton-web/src/test/groovy/org/bigbluebutton/web/controllers/ApiControllerSpec.groovy b/bigbluebutton-web/src/test/groovy/org/bigbluebutton/web/controllers/ApiControllerSpec.groovy index bfa3c8c2f6..7d466a5070 100644 --- a/bigbluebutton-web/src/test/groovy/org/bigbluebutton/web/controllers/ApiControllerSpec.groovy +++ b/bigbluebutton-web/src/test/groovy/org/bigbluebutton/web/controllers/ApiControllerSpec.groovy @@ -72,7 +72,7 @@ class ApiControllerSpec extends Specification implements ControllerUnitTest packages_to_skip.txt -echo "We will re-use the following packages:" +echo "We will reuse the following packages:" cat packages_to_skip.txt diff --git a/build/packages-template/bbb-export-annotations/opts-jammy.sh b/build/packages-template/bbb-export-annotations/opts-jammy.sh index 9330c6aef9..8d0049409b 100644 --- a/build/packages-template/bbb-export-annotations/opts-jammy.sh +++ b/build/packages-template/bbb-export-annotations/opts-jammy.sh @@ -1,3 +1,3 @@ . ./opts-global.sh -OPTS="$OPTS -t deb -d nodejs,npm,bbb-apps-akka,bbb-web,cairosvg,ghostscript,imagemagick" +OPTS="$OPTS -t deb -d nodejs,npm,bbb-apps-akka,bbb-web,cairosvg,ghostscript,imagemagick,poppler-utils" diff --git a/build/packages-template/bbb-webrtc-sfu/build.sh b/build/packages-template/bbb-webrtc-sfu/build.sh index 0813ccb6fb..58381ad6b4 100755 --- a/build/packages-template/bbb-webrtc-sfu/build.sh +++ b/build/packages-template/bbb-webrtc-sfu/build.sh @@ -40,7 +40,7 @@ else npm install --unsafe-perm --production fi -# clean out stuff that is not required in the final package. Most of this are object files from dependant libraries +# clean out stuff that is not required in the final package. Most of this are object files from dependent libraries rm -rf node_modules/mediasoup/worker/out/Release/subprojects rm -rf node_modules/mediasoup/worker/out/Release/mediasoup-worker.p rm -rf node_modules/mediasoup/worker/out/Release/deps diff --git a/build/push_packages.sh b/build/push_packages.sh index 199340b53c..1d3c7e10a6 100755 --- a/build/push_packages.sh +++ b/build/push_packages.sh @@ -3,7 +3,7 @@ # This script uploads the packages to the CI repo server. Its counterpart # on the server end is ci-repo-upload/cgi-bin/incoming.py. The variable # ADDITIONAL_PACKAGE_FILES contains a comma-separated list of the package -# files that the change detection decided to re-use for this build, since +# files that the change detection decided to reuse for this build, since # the contents have not changed since that commit. ADDITIONAL_PACKAGE_FILES="$(awk '{print $2}' < packages_to_skip.txt | tr '\n' ',' | sed 's/,*$//')" diff --git a/docs/README.md b/docs/README.md index a9514df85c..8e6450a09b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,7 +41,7 @@ Most changes are reflected live without having to restart the server. There is also a script `build.sh` that goes through all branches of the repository and adds all release branches that have a `docusaurus.config.js`-file as versions to the docs. -Note that you can not have uncommited local changes before you run `/build.sh`, +Note that you can not have uncommitted local changes before you run `/build.sh`, otherwise git will refuse to change branches. This step is optional and if you don't run it, docusaurus will only build the currently checkout out version which is recommended for local development diff --git a/docs/docs/accessiblity.md b/docs/docs/accessiblity.md index cafa511b73..e45e5141d7 100644 --- a/docs/docs/accessiblity.md +++ b/docs/docs/accessiblity.md @@ -69,12 +69,12 @@ HTML5 by default uses the `outline` attribute to visually indicate focus. Due to ![Image showing join audio aria label over the join audio icon](/img/accessibility-focusring-hc.jpg) -Aria labels are important to focus when navigating with a screen reader, these labels have been used extensivley through out the client to provide audible announcments for selected +Aria labels are important to focus when navigating with a screen reader, these labels have been used extensivley through out the client to provide audible announcements for selected elements. #### Keyboard Navigation -The HTML5 Client has made several improvements to the default keyboard navigation. The most notable addition being breakout room managment, assigning users to various rooms is now possible. +The HTML5 Client has made several improvements to the default keyboard navigation. The most notable addition being breakout room management, assigning users to various rooms is now possible. ![Animated image showing assignment of users to different rooms](/img/accessibility-br-manage.gif) diff --git a/docs/docs/administration/configure-firewall.md b/docs/docs/administration/configure-firewall.md index 6151036f07..50e76b17b8 100644 --- a/docs/docs/administration/configure-firewall.md +++ b/docs/docs/administration/configure-firewall.md @@ -51,7 +51,7 @@ If you are using EC2, you should also assign your server an [Elastic IP address] ### Azure -On Microsot Azure, when you create an instance you need to add the following inbound port rules to enable incomming connections on ports 80, 443, and UDP port range 16384-32768: +On Microsot Azure, when you create an instance you need to add the following inbound port rules to enable incoming connections on ports 80, 443, and UDP port range 16384-32768: ![Azure Cloud ](/img/azure-firewall.png?raw=true 'Azure 80, 443, and UDP 16384-32768') @@ -219,7 +219,7 @@ externalIPv4=192.0.2.0 ### Update FreeSWITCH -Let's revist the typical setup for BigBlueButton behind a firewall (yours would have different IP address of course). +Let's revisit the typical setup for BigBlueButton behind a firewall (yours would have different IP address of course). ![Install](/img/11-install-net2.png) @@ -299,7 +299,7 @@ freeswitch: port: 5066 ``` -If your runnig 2.2.29 or later, the value of `sip_ip` depends on whether you have `sipjsHackViaWs` +If your running 2.2.29 or later, the value of `sip_ip` depends on whether you have `sipjsHackViaWs` set to true or false in `/etc/bigbluebutton/bbb-html5.yml`. You also need to [setup Kurento to use a STUN server](#extra-steps-when-server-is-behind-nat). diff --git a/docs/docs/administration/customize.md b/docs/docs/administration/customize.md index 499b2f7de3..443a7642b8 100644 --- a/docs/docs/administration/customize.md +++ b/docs/docs/administration/customize.md @@ -299,7 +299,7 @@ and do `systemctl daemon-reload`. This file overrides the timing of when systemd #### Allow all recordings to be returned -In 2.6.x a new configuration property, `allowFetchAllRecordings`, was added to `bigbluebutton.properties`. This property determines whether every recording on the server can be returned in a single response from a `getRecordings` call. By default this property is set to `true`. On a server with a large number of recordings an attempt to return every recording in a sinlge response can cause a large amount of load on the server and therefore it is advised that this property be switched to `false`. When this is done any request to `getRecordings` that does not specify any recording or meeting IDs as well as no pagination parameters will return no recordings to prevent all recordings from being returned. +In 2.6.x a new configuration property, `allowFetchAllRecordings`, was added to `bigbluebutton.properties`. This property determines whether every recording on the server can be returned in a single response from a `getRecordings` call. By default this property is set to `true`. On a server with a large number of recordings an attempt to return every recording in a single response can cause a large amount of load on the server and therefore it is advised that this property be switched to `false`. When this is done any request to `getRecordings` that does not specify any recording or meeting IDs as well as no pagination parameters will return no recordings to prevent all recordings from being returned. #### Increase the number of recording workers @@ -467,7 +467,7 @@ cameraProfiles: The settings for `bitrate` are in kbits/sec (i.e. 100 kbits/sec). After your modify the values, save the file, restart your BigBlueButton server `sudo bbb-conf --restart` to have the settings take effect. The lowest setting allowed for WebRTC is 30 Kbits/sec. -If you have sessions that like to share lots of webcams, such as ten or more, then then setting the `bitrate` for `low` to 50 and `medium` to 100 will help reduce the overall bandwidth on the server. When many webcams are shared, the size of the webcams get so small that the reduction in `bitrate` will not be noticable during the live sessions. +If you have sessions that like to share lots of webcams, such as ten or more, then then setting the `bitrate` for `low` to 50 and `medium` to 100 will help reduce the overall bandwidth on the server. When many webcams are shared, the size of the webcams get so small that the reduction in `bitrate` will not be noticeable during the live sessions. #### Disable webcams @@ -537,7 +537,7 @@ For **live meetings**, the following parameters can be changed: The bitrate is specified in kbps and represents screen sharing's maximum bandwidth usage. Setting it to a higher value *may* improve quality but also increase bandwidth usage, while setting it to a lower value *may* reduce quality but will reduce average bandwidth usage. The constraints are specified as an YAML object with the same semantics as the [MediaTrackConstraints](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints) from the WebRTC specification. We recommend checking the aforementioned MDN link as well as the [Media Capture and Streams API spec](https://www.w3.org/TR/mediacapture-streams) for an extensive list of constraints. To set new screen sharing constraints, translate the JSON constraints object into an YAML format object and put it into `public.kurento.screenshare.constraints`. Restart bbb-html5 afterwards. -As an example, suppose you want to set the maximum screen sharing resolution to 1080p, alter the maxium bitrate to 2000 kbps and set a 10 FPS target. The following would need to be added to `etc/bigbluebutton/bbb-html5.yml`: +As an example, suppose you want to set the maximum screen sharing resolution to 1080p, alter the maximum bitrate to 2000 kbps and set a 10 FPS target. The following would need to be added to `etc/bigbluebutton/bbb-html5.yml`: ```yaml public: kurento: @@ -605,9 +605,9 @@ total 92 -rw-rw-r-- 1 kurento kurento 10823 Sep 13 17:10 2020-09-13T170908.00000.pid5956.log ``` -Now, if you now join a session and choose listen only (which causes Kurento setup a single listen only stream to FreeSWITCH), share your webcam, or share your screen, you'll see updates occuring independently to each of the above log files as each KMS process handles your request. +Now, if you now join a session and choose listen only (which causes Kurento setup a single listen only stream to FreeSWITCH), share your webcam, or share your screen, you'll see updates occurring independently to each of the above log files as each KMS process handles your request. -To revert back to running a single KMS server (which handles all three meida streams), change the above line in `/etc/bigbluebutton/bbb-conf/apply-config.sh` to +To revert back to running a single KMS server (which handles all three media streams), change the above line in `/etc/bigbluebutton/bbb-conf/apply-config.sh` to ```sh disableMultipleKurentos @@ -643,7 +643,7 @@ Thus, we recommend you [enable multiple Kurento](/administration/customize#run-t BigBlueButton will dynamically reduce the number of webcams in a meeting as the meeting grows larger. These are set in `/usr/share/meteor/bundle/programs/server/assets/app/config/settings.yml`, but you can override them by placing them in `/etc/bigbluebutton/bbb-html5.yml`. -For example, the follwing `/etc/bigbluebutton/bbb-html5.yml` file would ensure that no single meeting will have more than 300 streams. For example, in a meeting with 30 users, the moderator will see 25 webcams and the viewers 6 webcams. This gives 25 + 29 _ 6 = 196 webcam streams. If the meeting grows to 100 users, the moderator will see 8 webcams and viewers will see 2 webcams. This gives 8 + 99 _ 2 = 206 webcam streams. +For example, the following `/etc/bigbluebutton/bbb-html5.yml` file would ensure that no single meeting will have more than 300 streams. For example, in a meeting with 30 users, the moderator will see 25 webcams and the viewers 6 webcams. This gives 25 + 29 _ 6 = 196 webcam streams. If the meeting grows to 100 users, the moderator will see 8 webcams and viewers will see 2 webcams. This gives 8 + 99 _ 2 = 206 webcam streams. ``` public: @@ -864,7 +864,7 @@ To create the dialplan, use the XML below and save it to `/opt/freeswitch/conf/d - + @@ -887,7 +887,7 @@ To create the dialplan, use the XML below and save it to `/opt/freeswitch/conf/d - + @@ -1721,9 +1721,9 @@ total 92 -rw-rw-r-- 1 kurento kurento 10823 Sep 13 17:10 2020-09-13T170908.00000.pid5956.log ``` -Now, if you now join a session and choose listen only (which causes Kurento setup a single listen only stream to FreeSWITCH), share your webcam, or share your screen, you'll see updates occuring independently to each of the above log files as each KMS process handles your request. +Now, if you now join a session and choose listen only (which causes Kurento setup a single listen only stream to FreeSWITCH), share your webcam, or share your screen, you'll see updates occurring independently to each of the above log files as each KMS process handles your request. -To revert back to running a single KMS server (which handles all three meida streams), change the above line in `/etc/bigbluebutton/bbb-conf/apply-config.sh` to +To revert back to running a single KMS server (which handles all three media streams), change the above line in `/etc/bigbluebutton/bbb-conf/apply-config.sh` to ```sh disableMultipleKurentos diff --git a/docs/docs/administration/install.md b/docs/docs/administration/install.md index 8f4b013b47..e307f066d0 100644 --- a/docs/docs/administration/install.md +++ b/docs/docs/administration/install.md @@ -157,7 +157,7 @@ At the moment, the requirement for docker may preclude running 3.0 within some v ## Install -To install BigBlueButton, use [bbb-install.sh](https://github.com/bigbluebutton/bbb-install/blob/v3.0.x-release/bbb-install.sh) script. Notice that this command is slightly different than what we recommended in previous versions of BigBlueButton. The script now resides on a branch specifying the version of BigBlueButton, but otherwise the name of the script is identical accross different branches. This makes it more maintainable as patches done to the script in one branch can be easily applied to other branches. +To install BigBlueButton, use [bbb-install.sh](https://github.com/bigbluebutton/bbb-install/blob/v3.0.x-release/bbb-install.sh) script. Notice that this command is slightly different than what we recommended in previous versions of BigBlueButton. The script now resides on a branch specifying the version of BigBlueButton, but otherwise the name of the script is identical across different branches. This makes it more maintainable as patches done to the script in one branch can be easily applied to other branches. The above link gives detailed information on using the script. As an example, passing several arguments to the script you can easily have both BigBlueButton and Greenlight or LTI installed on the same server. You could specify if you would like a new certificate to be generated. A firewall could be enabled. For the most up-to-date information, please refer to the instructions in the script. Notice that as of BigBlueButton 2.6 we have retired the API demos. We recommend using Greenlight or [API MATE](https://mconf.github.io/api-mate/) instead. @@ -359,7 +359,7 @@ If this server is intended for production, you should also - [Set up a TURN server](/administration/turn-server) (if your server is on the Internet and you have users accessing it from behind restrictive firewalls) - Test your HTTPS configuration. A well-respected site that can do a series of automated tests is [https://www.ssllabs.com/ssltest/](https://www.ssllabs.com/ssltest/) - simply enter your server's hostname, optionally check the "Do not show results" check box if you would like to keep it private, then Submit. At time of writing, the configuration shown on this page should achieve an "A" ranking in the SSL Labs test page. -We provide publically accessible servers that you can use for testing: +We provide publicly accessible servers that you can use for testing: - [https://demo.bigbluebutton.org](https://demo.bigbluebutton.org/) - a pool of BigBlueButton servers with the Greenlight front-end (sometimes the pool is a mix of different BigBlueButton releases) - [https://test30.bigbluebutton.org](https://test30.bigbluebutton.org) - Runs the general build of BigBlueButton 3.0 - usually a few days behind the repository branch `v3.0.x-release` @@ -384,16 +384,12 @@ Choose this method if you are already comfortable with a lot of the technical kn Note: These examples are _not_ maintained or developed by the official BigBlueButton developers. These are entirely community-sourced, use at your own discretion. -These first two install BigBlueButton on your server in a consistent fashion. You can specify variables, such as whether to install Greenlight too, what ports to use for TURN, and others. Functionally quite similar to bbb-install.sh but highly automated. +The first install BigBlueButton on your server in a consistent fashion. You can specify variables, such as what ports to use for TURN, and others. Functionally quite similar to bbb-install.sh but highly automated. -- [General Ansible role for BigBlueButton](https://github.com/n0emis/ansible-role-bigbluebutton) -- [Alternative Ansible role for BigBlueButton](https://github.com/juanluisbaptiste/ansible-bigbluebutton) +- [General Ansible role for BigBlueButton](https://github.com/ebbba-org/ansible-role-bigbluebutton) Large scale deployments must include several other components in addition to the core BigBlueButton packages. These include Scalelite, Greenlight, a database, backups, nginx configurations, and more. -- [Full out-of-the-box setup with wiki, chat, backups](https://github.com/stadtulm/a13-ansible) -- [Full out-of-the-box setup with frontend on one machine](https://github.com/srcf/timeout) -- [Full setup for a university](https://github.com/unistra/bigbluebutton/) - [Full HA setup with PeerTube, Conferences Streaming, EFK, Prometheus, backups](https://github.com/Worteks/bbb-ansible) ## Customizations diff --git a/docs/docs/administration/nextcloud.md b/docs/docs/administration/nextcloud.md index a529b5673d..cb07fbe5e6 100644 --- a/docs/docs/administration/nextcloud.md +++ b/docs/docs/administration/nextcloud.md @@ -11,7 +11,7 @@ keywords: ## Nextcloud This following Nextcloud documentation includes some tweaks we need to make -in order to propperly install Nextcloud with the BBB plugin integration. +in order to properly install Nextcloud with the BBB plugin integration. ## Install @@ -23,7 +23,7 @@ for more information. With Nextcloud up and running, let's install and configure the BigBlueButton plugin: - - Folow through with [Klaus' repository guidance](https://github.com/sualko/cloud_bbb#rocket-install-it); + - Follow through with [Klaus' repository guidance](https://github.com/sualko/cloud_bbb#rocket-install-it); - Proceed with "To install it change into your Nextcloud's apps directory"; - If some errors appear, upgrade node's version to `14.21.2`, and run `make build` again; - Then go to your profile in the Nexcloud server > `Apps` > `BigBlueButton Integration` > @@ -74,10 +74,10 @@ on how to install and configure the Nextcloud server. ### Step-by-step to install Nextcloud - - Folow the steps on [the official documentation](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_ubuntu.html) + - Follow the steps on [the official documentation](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_ubuntu.html) - When you get to the part `"Now download the archive of the latest Nextcloud version"`, it changed a little: - Scroll down the [page](https://nextcloud.com/install/); - - In the section "DOWNLOAD SERVER" click on "COMUNITY PROJECTS" + - In the section "DOWNLOAD SERVER" click on "COMMUNITY PROJECTS" - Scroll down a little more; - Now, in the section "archive", under the `"Get ZIP file"` button you'll find the `.tar.bz2` files to upload it to your server; @@ -97,7 +97,7 @@ the following. This might be a tricky part, and you can surely use another SSL certificate, but here I am going to cover `let's encrypt`, as [suggested by them](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#enabling-ssl). - - Folow [these commands](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#enabling-ssl) + - Follow [these commands](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#enabling-ssl) - Now go to [digital ocean tutorial](https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-22-04) on how to configure the let's encrypt certificate in an `apache server` and follow through (there is no need to create `/etc/apache2/sites-available/your_domain.conf` because @@ -129,4 +129,4 @@ It may look something like this (`/etc/apache2/sites-available/000-default.conf` - If even with all these solutions your let's encrypt is not working, follow on with one of [these alternatives](https://help.nextcloud.com/t/domain-not-working-after-letsencrypt/83862), particularly this one: -`"The default vhost is used whenever a client is accesing your server by direct IP-addres(...)"` +`"The default vhost is used whenever a client is accessing your server by direct IP-addres(...)"` diff --git a/docs/docs/administration/privacy.md b/docs/docs/administration/privacy.md index 5128e35d31..7ebf569d3c 100644 --- a/docs/docs/administration/privacy.md +++ b/docs/docs/administration/privacy.md @@ -17,7 +17,7 @@ Disclaimer: the following documentation is neither legal advice, nor complete. T ## BigBlueButton -This section documents privacy related settings, defaults, and configuration options in BigBlueButton itself. Keep in mind that your configration changes here may be silently overwritten upon upgrades via apt, see [issue 9111](https://github.com/bigbluebutton/bigbluebutton/issues/9111) +This section documents privacy related settings, defaults, and configuration options in BigBlueButton itself. Keep in mind that your configuration changes here may be silently overwritten upon upgrades via apt, see [issue 9111](https://github.com/bigbluebutton/bigbluebutton/issues/9111) To prevent this, make sure to use the [`apply-config.sh` script](/administration/customize#automatically-apply-configuration-changes-on-restart) to ensure changes are retained upon upgrades and restarts. ### Recordings @@ -186,7 +186,7 @@ The default installation of FreeSWITCH by default logs with loglevel DEBUG. This #### kurento -Logs session names and timestamps, as well as user IP addresses. This also includes user IP addresses behind NATs, i.e., the actual client addresses, potentially making users identifiable accross sessions. This can be configured in `/etc/default/kurento-media-server`, see [Kurento logging](https://doc-kurento.readthedocs.io/en/latest/features/logging.html) +Logs session names and timestamps, as well as user IP addresses. This also includes user IP addresses behind NATs, i.e., the actual client addresses, potentially making users identifiable across sessions. This can be configured in `/etc/default/kurento-media-server`, see [Kurento logging](https://doc-kurento.readthedocs.io/en/latest/features/logging.html) Note that this can most likely be overridden by kurento's systemd unit file. Hence, `--gst-debug-level=1` should also be set in `/usr/lib/systemd/system/kurento-media-server.service`. @@ -217,7 +217,7 @@ By default, when Greenlight creates a conference, the value 'record=true' is pas #### Resolution -You can disable the recording globally in the Greenlight room settings for everyone or optinally for everyone in their room. see: [pull request 1296](https://github.com/bigbluebutton/greenlight/pull/1296) Alternatively, if necessary, completely disable the recording feature in the BigBlueButton server configuration. +You can disable the recording globally in the Greenlight room settings for everyone or optionally for everyone in their room. see: [pull request 1296](https://github.com/bigbluebutton/greenlight/pull/1296) Alternatively, if necessary, completely disable the recording feature in the BigBlueButton server configuration. ### Greenlight does not request consent to a privacy policy and/or recording of a session when joining a room as a guest. diff --git a/docs/docs/administration/turn-server.md b/docs/docs/administration/turn-server.md index 30e76c2d0c..ffeef63eb3 100644 --- a/docs/docs/administration/turn-server.md +++ b/docs/docs/administration/turn-server.md @@ -345,13 +345,13 @@ Nat filtering: Endpoint Independent Filtering If you get an error, check that `coturn` is running on the TURN server using `systemctl status coturn.service`. Check the logs by doing `tail -f /var/log/turnserver/coturn.log`. You can get verbose logs by adding `verbose` to `/etc/turnserver.conf` and restarting the TURN server `systemctl restart coturn.service` -You can test your TURN server using the [trickle ICE](https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/) page. This gives you a log of the relay candidates as they are returned from ICE gathering. To test using this page, you need to generate some test credentials. Run the following BASH script and substitute `` with the hostname of your TURN server and `` with the password for your TURN server. +You can test your TURN server using the [trickle ICE](https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/) page. This gives you a log of the relay candidates as they are returned from ICE gathering. To test using this page, you need to generate some test credentials. The following BASH script generates them by reading your `/etc/turnserver.conf`. Alternatively, set `HOST=` and `SECRET=` to your TURN servers credentials. ```bash #!/bin/bash -HOST= -SECRET= +HOST=$(cat /etc/turnserver.conf | grep realm | sed 's/realm=//') +SECRET=$(cat /etc/turnserver.conf | grep static-auth-secret | sed 's/static-auth-secret=//') time=$(date +%s) expiry=8400 diff --git a/docs/docs/data/create.tsx b/docs/docs/data/create.tsx index 17eac2e6e5..bc1c8e1a29 100644 --- a/docs/docs/data/create.tsx +++ b/docs/docs/data/create.tsx @@ -59,7 +59,7 @@ const createEndpointTableData = [ "name": "record", "required": false, "type": "Boolean", - "description": (<>Setting ‘record=true’ instructs the BigBlueButton server to record the media and events in the session for later playback. The default is false.

In order for a playback file to be generated, a moderator must click the Start/Stop Recording button at least once during the sesssion; otherwise, in the absence of any recording marks, the record and playback scripts will not generate a playback file. See also the autoStartRecording and allowStartStopRecording parameters in bigbluebutton.properties.) + "description": (<>Setting ‘record=true’ instructs the BigBlueButton server to record the media and events in the session for later playback. The default is false.

In order for a playback file to be generated, a moderator must click the Start/Stop Recording button at least once during the session; otherwise, in the absence of any recording marks, the record and playback scripts will not generate a playback file. See also the autoStartRecording and allowStartStopRecording parameters in bigbluebutton.properties.) }, { "name": "duration", diff --git a/docs/docs/development/api.md b/docs/docs/development/api.md index ebbbe89eab..df947ed871 100644 --- a/docs/docs/development/api.md +++ b/docs/docs/development/api.md @@ -141,7 +141,7 @@ Here's a sample return Secret: ECCJZNJWLPEA3YB6Y2LTQGQD3GJZ3F93 ``` -You should _not_ embed the shared secret within a web page and make BigBlueButton API calls within JavaScript running within a browser. The built-in debugging tools for modern browser would make this secret easily accessibile to any user. Once someone has the shared secret for your BigBlueButton server, they could create their own API calls. The shared secret should only be accessibile to the server-side components of your application (and thus not visible to end users). +You should _not_ embed the shared secret within a web page and make BigBlueButton API calls within JavaScript running within a browser. The built-in debugging tools for modern browser would make this secret easily accessible to any user. Once someone has the shared secret for your BigBlueButton server, they could create their own API calls. The shared secret should only be accessible to the server-side components of your application (and thus not visible to end users). ### Configuration @@ -169,7 +169,26 @@ $ sudo bbb-conf --setsecret \$(openssl rand -base64 32 | sed 's/=//g' | sed 's/+ There are other configuration values in bbb-web's configuration `bigbluebutton.properties` (overwritten by `/etc/bigbluebutton/bbb-web.properties` ) related to the lifecycle of a meeting. You don't need to understand all of these to start using the BigBlueButton API. For most BigBlueButton servers, you can leave the [default values](https://github.com/bigbluebutton/bigbluebutton/blob/main/bigbluebutton-web/grails-app/conf/bigbluebutton.properties). -In 2.5 support for additional hashing algorithms, besides sha1 and sha256, were added. These include sha384 and sha512. The `supportedChecksumAlgorithms` property in `bigbluebutton.properties` defines which algorithms are supported. By default checksums can be validated with any of the supported algorithms. To remove support for one or more of these algorithms simply delete it from the configuration file. +In BigBlueButton 2.5 support for additional hashing algorithms, besides sha1 and sha256, were added. These include sha384 and sha512. The `supportedChecksumAlgorithms` property in bbb-web defines which algorithms are supported. By default checksums can be validated with any of the supported algorithms. To remove support for one or more of these algorithms simply delete it from the configuration file. +If you drop support for sha256, (for example if you want to force only sha512 to be used) you will also need to update the `checkSumAlgorithmForBreakouts` property in akka-apps. + +In `/etc/bigbluebutton/bbb-web.properties`: + +```properties +supportedChecksumAlgorithms=sha512 +``` + +In `/etc/bigbluebutton/bbb-apps-akka.conf`: + +```properties +services { + checkSumAlgorithmForBreakouts = "sha512" + #... +} +``` + +And make sure to restart BigBlueButton. + ### Usage @@ -310,7 +329,7 @@ http://yourserver.com/bigbluebutton/api/create?[parameters]&checksum=[checks ``` #### POST request -You can also include a payload in the request, it may be usefull in cases where some of the query parameters are big enough to exceed the maximum number of characters in URLs. BigBlueButton supports a POST request where the parameters that usually would be passed in the URL, can be sent through the body, see example below: +You can also include a payload in the request, it may be useful in cases where some of the query parameters are big enough to exceed the maximum number of characters in URLs. BigBlueButton supports a POST request where the parameters that usually would be passed in the URL, can be sent through the body, see example below: ```bash curl --request POST \ diff --git a/docs/docs/development/localization.md b/docs/docs/development/localization.md index 578bf0a5e6..1169173790 100644 --- a/docs/docs/development/localization.md +++ b/docs/docs/development/localization.md @@ -31,6 +31,6 @@ You'll see a list of languages and components of BigBlueButton ready for transla #### Note: The localized strings are included in BigBlueButton's packages -We use an integration between Transifex (where the strings are translated) and GitHub (where BigBlueButton's source code is hosted). The integration syncronizes the fully translated strings so that they are ready to be included in the upcoming BigBlueButton release. [Example of an automated pull request from Transifex:](https://github.com/bigbluebutton/bigbluebutton/pull/17799) +We use an integration between Transifex (where the strings are translated) and GitHub (where BigBlueButton's source code is hosted). The integration synchronizes the fully translated strings so that they are ready to be included in the upcoming BigBlueButton release. [Example of an automated pull request from Transifex:](https://github.com/bigbluebutton/bigbluebutton/pull/17799) We receive pull requests from Transifex when a localized language reaches 100% completion OR when a localized string is updated in a 100% localized locale. This means that if you made a recent modification to the strings and you're not seeing it in the latest version of BigBlueButton, likely either the locale is not 100% complete, or there has been no new BigBlueButton release on the specific branch since you made the changes. diff --git a/docs/docs/new-features.md b/docs/docs/new-features.md index 6439ef334c..8ca1d19b6d 100644 --- a/docs/docs/new-features.md +++ b/docs/docs/new-features.md @@ -76,6 +76,11 @@ Recent releases: We have removed all use of Kurento Media Server. For the live media transmission we still rely on mediasoup. For the recording portion we make use of our own component `bbb-webrtc-recorder`. BigBlueButton 3.0 is the first release where we do not even install Kurento. +#### Improved support for various SHA algorithms for checksum calculation + +In BigBlueButton 2.6.17/2.7.5/3.0.0-alpha.5 we added a new configuration property for bbb-apps-akka package under `services` called `checkSumAlgorithmForBreakouts`. By default the value is `"sha256"`. It controls the algorithm for checksum calculation for the breakout rooms join link. In case you overwrite bbb-web's `supportedChecksumAlgorithms` property removing sha256 you will need to set a supported algorithm here too. For example if you want to only use `sha512`, set `supportedChecksumAlgorithms=sha512` in `/etc/bigbluebutton/bbb-web.properties` and also set `checkSumAlgorithmForBreakouts="sha512"` in `/etc/bigbluebutton/bbb-apps-akka.conf` and then restart BigBlueButton. + + ### Development For information on developing in BigBlueButton, see [setting up a development environment for 3.0](/development/guide). diff --git a/docs/docs/release-notes.md b/docs/docs/release-notes.md index 6318194200..26617f2042 100644 --- a/docs/docs/release-notes.md +++ b/docs/docs/release-notes.md @@ -18,7 +18,7 @@ Released: November 6, 2019 ([Installation Instructions](/administration/install) We made it! -After months of testing with the community, millions of sessions hosted by commercial companies using BigBlueButton, and interacting with hundreds of people on our mailing lists that help us find and fix any issues, we are announcing the releae of BigBlueButton 2.2. +After months of testing with the community, millions of sessions hosted by commercial companies using BigBlueButton, and interacting with hundreds of people on our mailing lists that help us find and fix any issues, we are announcing the release of BigBlueButton 2.2. Enjoy! @@ -141,7 +141,7 @@ This is our eleventh release of BigBlueButton. For a quick summary of what's ne * **New APIs** - The BigBlueButton API now includes the ability to dynamically configure each client on a per-user bases, thus enabling developers to configure the skin, layout, modules, etc. for each user. There is also a JavaScript interface to control the client. -* **Accessiblity for screen readers** - BigBlueButton adds accessibility by supporting screen readers such as JAWS (version 11+) and NVDA. A list of keyboard shortcuts have been added to make it easier to navigate through the interface using the keyboard. +* **Accessibility for screen readers** - BigBlueButton adds accessibility by supporting screen readers such as JAWS (version 11+) and NVDA. A list of keyboard shortcuts have been added to make it easier to navigate through the interface using the keyboard. * **LTI Support** - BigBlueButton is IMS Learning Tools Interoperability (LTI) 1.0 compliant. This means any LTI consumer can integrate with BigBlueButton without requiring custom plug-ins (see [BigBlueButton LTI certification](http://www.imsglobal.org/cc/detail.cfm?ID=172) and [video](http://www.youtube.com/watch?v=OSTGfvICYX4)). @@ -427,7 +427,7 @@ If you are running a BigBlueButton VM or had installed BigBlueButton using packa sudo apt-get upgrade ``` -**Note:** If you get an error during upgrade, just run `sudo apt-get upgrade` again. We refactored the install scripts and a previous install script and new install scrip both reference the same configuration file. Running the upgrade command a second time will solve the problem as the first time upgrades all the install script. +**Note:** If you get an error during upgrade, just run `sudo apt-get upgrade` again. We refactored the install scripts and a previous install script and new install script both reference the same configuration file. Running the upgrade command a second time will solve the problem as the first time upgrades all the install script. ### Fixed Issues diff --git a/docs/docs/support/faq.md b/docs/docs/support/faq.md index 5efefaed6a..55a9b1940a 100644 --- a/docs/docs/support/faq.md +++ b/docs/docs/support/faq.md @@ -300,7 +300,7 @@ Yes. The steps are covered in the [install](/administration/install) documentati #### Ubuntu -Older versions of BigBlueButton, up to and including version 2.4, required **Ubuntu 18.04 64-bit**. The current version of BigBlueButto n2.5 requires **Ubuntu 20.04 64-bit**. See [Install BigBlueButton](/administration/install). +Older versions of BigBlueButton, up to and including version 2.7, required **Ubuntu 20.04 64-bit**. BigBlueButton 3.0 requires **Ubuntu 22.04 64-bit**. See [Install BigBlueButton](/administration/install). We (the core developers) have not installed BigBlueButton on any other version of Ubuntu. It probably won't work. @@ -511,7 +511,7 @@ When a front-end makes an API request to BigBlueButton, the BigBlueButton server When the BigBlueButton client loads, it makes data connections back to the BigBlueButton server using a web socket connection encrypted HTTPS. When the BigBlueButton shares the user's audio, video, or screen, the browser uses the built-in web real-time communication (WebRTC) libraries that transmit real-time protocol packets (RTP) over user datagram protocol (UDP) via Datagram Transport Layer Security (see [DTLS](https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security)). Furthermore, to provide communications privacy for datagram protocols the media packets are encrypted using the Secure Real-Time Protocol (see [SRTP](https://en.wikipedia.org/wiki/Secure_Real-time_Transport_Protocol)). -As described above, by saying there are _multiple_ security mechanisms BigBlueButton, does this mean BigBlueButton offers secure collaboration? No. No system is really secure, there are only levels of security. We care about security in the BigBlueButton project, and if you detect any security vunerabilities in the project, you can make a responsible disclosure by emailing us at security@bigbluebutton.org. +As described above, by saying there are _multiple_ security mechanisms BigBlueButton, does this mean BigBlueButton offers secure collaboration? No. No system is really secure, there are only levels of security. We care about security in the BigBlueButton project, and if you detect any security vulnerabilities in the project, you can make a responsible disclosure by emailing us at security@bigbluebutton.org. ### Front Ends diff --git a/docs/docs/support/troubleshooting.md b/docs/docs/support/troubleshooting.md index 41f21be441..29c32666aa 100644 --- a/docs/docs/support/troubleshooting.md +++ b/docs/docs/support/troubleshooting.md @@ -222,7 +222,7 @@ $ systemctl unmask kurento-media-server.service ### Unable to share webcam -The default installation of BigBlueButton should work in most netowrk configurations; however, if your users ae behind a restrictive network that blocks outgoing UDP connections, they may encounter 1020 errors (media unable to reach server). +The default installation of BigBlueButton should work in most network configurations; however, if your users ae behind a restrictive network that blocks outgoing UDP connections, they may encounter 1020 errors (media unable to reach server). If you get reports of these errors, setup TURN server to help their browsers send WebRTC audio and video streams via TCP over port 443 to the TURN server. The TURN server will then relay the media to your BigBlueButton server. @@ -529,7 +529,7 @@ You can add a line in `/etc/bigbluebutton/bbb-conf/apply-conf.sh` to always appl xmlstarlet edit --inplace --update '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_rtp_ip=")]/@data' --value "external_rtp_ip=234.32.3.3" /opt/freeswitch/conf/vars.xml ``` -Note: If your server has an internal/exteral IP address, such as on AWS EC2 server, be sure to set it to the external IP address configure a dummy network interface card (see [Update FreeSWITCH](/administration/firewall-configuration#update-freeswitch)). +Note: If your server has an internal/external IP address, such as on AWS EC2 server, be sure to set it to the external IP address configure a dummy network interface card (see [Update FreeSWITCH](/administration/firewall-configuration#update-freeswitch)). ## HTML5 Server @@ -973,7 +973,7 @@ The script `bbb-install` now creates these overrides by default. It is most likely an error on GreenLight. Check the log file according to [Troubleshooting Greenlight](/greenlight/v3/install). -If this error occurrs on just a small number of PCs accessing a BigBlueButton server within a LAN through a proxy server and you find the description "Error::Unsafe Host Error (x.x.x.x is not a safe host)" (where x.x.x.x is an IP address) in the log file, check if the "Don't use the proxy server for local (intranet) addresses" (in the Windows proxy setting) is ticked. +If this error occurs on just a small number of PCs accessing a BigBlueButton server within a LAN through a proxy server and you find the description "Error::Unsafe Host Error (x.x.x.x is not a safe host)" (where x.x.x.x is an IP address) in the log file, check if the "Don't use the proxy server for local (intranet) addresses" (in the Windows proxy setting) is ticked. ## Legacy errors diff --git a/docs/docs/testing/release-testing.md b/docs/docs/testing/release-testing.md index 8dd007231d..1114dad425 100644 --- a/docs/docs/testing/release-testing.md +++ b/docs/docs/testing/release-testing.md @@ -14,7 +14,7 @@ This document is meant to be a combination of manual and (labeled so) automated The automated tests are only a portion of the testing done before a release. Ideally they should be triggered often, for example when testing pull requests, or once a day automatically. The manual tests really help to ensure release quality. They should -be performed by humans using different browsers. It is usefull to have multiple +be performed by humans using different browsers. It is useful to have multiple humans performing these tests together. You should plan at least an hour to perform all of these tests. @@ -304,7 +304,7 @@ The webcam will be resized as per the size we want. B. Case of more than one webcam. -- Share atleast 2 webcams +- Share at least 2 webcams - Drag the bottom of the webcams container - Increase or Decrease the size of the webcams. @@ -387,7 +387,7 @@ The screen sharing stops, a sound effect of disconnection is heard and the prese ## Breakout rooms -### Moderators creating breakout rooms and assiging users [(Automated)](https://github.com/bigbluebutton/bigbluebutton/blob/v2.6.x-release/bigbluebutton-tests/playwright/breakout/breakout.spec.js) +### Moderators creating breakout rooms and assigning users [(Automated)](https://github.com/bigbluebutton/bigbluebutton/blob/v2.6.x-release/bigbluebutton-tests/playwright/breakout/breakout.spec.js) 1. Click "Manage users" (cog wheel icon in the user list). @@ -471,7 +471,7 @@ The screen sharing stops, a sound effect of disconnection is heard and the prese 2. Inside the breakout rooms control panel ("Breakout Rooms" button in the left-hand panel), select the "Breakout options" dropdown and choose "Destroy breakouts". -3. All of the breaout rooms should end and all users should get back to the main room. If users already got the audio on, they shouldn't get propmted for the audio modal. +3. All of the breaout rooms should end and all users should get back to the main room. If users already got the audio on, they shouldn't get prompted for the audio modal. ### Edit the duration of a breakout room @@ -698,7 +698,7 @@ Enable Microphone : This will cause a user name to appear on left top corner of 6. Presenter: Draw on the whiteboard area. -7. All clients should see the drawing and the drawing should appear according to the chosed thickness. +7. All clients should see the drawing and the drawing should appear according to the chosen thickness. ### Changing pencil tool colour @@ -820,7 +820,7 @@ Enable Microphone : This will cause a user name to appear on left top corner of 7. The result of those actions should be visible for all clients. -### Stoping Youtube Video Sharing +### Stopping Youtube Video Sharing 1. Join a meeting. @@ -1679,7 +1679,7 @@ Note : - Click "Accept" for the specific user in the waiting users panel. That viewer should be accepted into the meeting. -- Click "Deny" for the specific user in teh waiting users panel. That viewer should see the message "Guest denied of joining the meeting" and should soon be redirected to the home page. +- Click "Deny" for the specific user in the waiting users panel. That viewer should see the message "Guest denied of joining the meeting" and should soon be redirected to the home page. ## Recording