Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
166 commits
Select commit Hold shift + click to select a range
f079216
Fix allowPromoteGuestToModerator
blaniel Jun 12, 2026
f8b065e
fix(shared-notes): prevent collaboration cursor name from leaking int…
Tainan404 Jun 16, 2026
1531aa4
fix(chat): preserve text before links in reply message preview
imdt-claudiop Jun 11, 2026
cc0cfc2
test(shared-notes): harden #25225 regression test per review
Tainan404 Jun 16, 2026
6df858d
test(shared-notes): make #25225 cursor positioning deterministic
Tainan404 Jun 16, 2026
f2cbae3
fix(video-provider): show raised hand indicator on audio-only tiles
imdt-claudiop Jun 1, 2026
a8a85a1
test(video): skip audio-only raised hand test when feature disabled
imdt-claudiop Jun 9, 2026
ee4a464
[svg-notification] fix custom SVG not appearing in notification (toast)
GuiLeme Jun 16, 2026
818339f
adjust raise-hand audio-only tile test to use unified layout
ramonlsouza Jun 17, 2026
f820571
build(deps): bump markdown-it in /bigbluebutton-html5
dependabot[bot] Jun 17, 2026
a33e4cb
remove font-render-hinting flag from tests
ramonlsouza Jun 18, 2026
c3c33c5
Merge pull request #25280 from ramonlsouza/bp-25220
ramonlsouza Jun 18, 2026
9751279
Merge pull request #25274 from ramonlsouza/bp-25268
ramonlsouza Jun 18, 2026
d87fe92
add setting to not display guest lobby position
ramonlsouza Jun 19, 2026
e41e30b
update docs with showGuestLobbyWaitingQueuePosition
ramonlsouza Jun 19, 2026
04df937
Merge pull request #25297 from ramonlsouza/issue-25291
ramonlsouza Jun 19, 2026
504f1e9
test(shared-notes): dedupe WORD_JOINER constant in #25225 test
Tainan404 Jun 19, 2026
fe27b83
Merge pull request #25299 from bigbluebutton/v3.0.x-develop
ramonlsouza Jun 19, 2026
c7d5daa
chore: BigBlueButton release version to 3.0.31
ramonlsouza Jun 19, 2026
62b0d7b
chore: BigBlueButton release version to 3.0.31
ramonlsouza Jun 19, 2026
8a99394
include release 3.0.31
ramonlsouza Jun 19, 2026
fd9cb92
build(deps): bump form-data in /bigbluebutton-tests/playwright
dependabot[bot] Jun 21, 2026
408f27b
Merge pull request #25281 from GuiLeme/svg-notification
ramonlsouza Jun 22, 2026
ffc71ae
Set MALLOC_ARENA_MAX=2 for bbb-web and bbb-apps-akka
imdt-claudiop Jun 22, 2026
8c416f1
Merge pull request #25309 from imdt-claudiop/malloc-arena-max-jvm
TiagoJacobs Jun 22, 2026
87e9019
fix(bbb-graphql-server): lower connection_lifetime to limit Postgres …
imdt-claudiop Jun 22, 2026
ab7b61f
Merge pull request #25310 from imdt-claudiop/bbb-graphql-connection-l…
TiagoJacobs Jun 23, 2026
cc5eb3b
Translate en.json in fr
transifex-integration[bot] Jun 23, 2026
4c4c10e
Translate en.json in fr
transifex-integration[bot] Jun 23, 2026
94910b7
fix(bbb-export-annotations): add viewBox to background slides missing…
imdt-claudiop Jun 23, 2026
9832cf4
Merge pull request #25285 from Tainan404/i-25225-blocknote-cursor-in-…
ramonlsouza Jun 23, 2026
79cac2c
harden width/height regex in ensureSlideViewBox (CodeRabbit review)
imdt-claudiop Jun 23, 2026
ec5e9d4
add document-title-manager to handle title changes in each page
ramonlsouza Jun 23, 2026
06048be
add tests for title changes
ramonlsouza Jun 23, 2026
3b6395d
avoid no-op title events and guard optional breakout title test
ramonlsouza Jun 23, 2026
4c39d12
Add analytics logging for breakout move-user request
imdt-claudiop Jun 24, 2026
01459fc
Merge pull request #25326 from imdt-claudiop/breakout-move-user-analy…
TiagoJacobs Jun 24, 2026
5b826fa
update components to have better contrast between background and borders
ramonlsouza Jun 24, 2026
11525e2
add non-text constrast test
ramonlsouza Jun 24, 2026
d451153
restore distinct hover border for chat reactions
ramonlsouza Jun 24, 2026
ecde87d
check border contrast against inner and outer backgrounds
ramonlsouza Jun 24, 2026
4bac6ad
update shared notes test screenshot
ramonlsouza Jun 25, 2026
15d9e51
Merge pull request #25314 from bigbluebutton/translations_80e91e62420…
ramonlsouza Jun 26, 2026
3392861
Merge pull request #25315 from imdt-claudiop/fix/odf-export-image-cro…
TiagoJacobs Jun 26, 2026
d60158e
[update-sdk-version-0.0.102] sync sdk version last published
GuiLeme Jun 26, 2026
6f52408
Merge pull request #25336 from GuiLeme/update-sdk-version-0.0.102
ramonlsouza Jun 26, 2026
470216a
Merge pull request #25304 from bigbluebutton/dependabot/npm_and_yarn/…
ramonlsouza Jun 29, 2026
543ebb1
Merge pull request #25322 from ramonlsouza/i-25177-follow-up
ramonlsouza Jun 29, 2026
e1b3fd0
Merge pull request #25287 from bigbluebutton/dependabot/npm_and_yarn/…
ramonlsouza Jun 29, 2026
745e9e8
build(deps): bump ws from 7.5.10 to 7.5.11 in /docs
dependabot[bot] Jun 29, 2026
d866ef8
build(deps): bump form-data in /bbb-learning-dashboard
dependabot[bot] Jun 29, 2026
55f2bde
build(deps): bump ws in /bbb-learning-dashboard
dependabot[bot] Jun 29, 2026
5e0e174
Merge pull request #25261 from blaniel/fix-promote-guest
ramonlsouza Jun 29, 2026
72e5511
fix(whiteboard): prevent crash when slide changes while a viewer is e…
imdt-claudiop Jun 30, 2026
b177871
Merge pull request #25345 from imdt-claudiop/fix/whiteboard-editing-s…
ramonlsouza Jun 30, 2026
b34a72d
fix visible focus indicator for chat message input wrapper
ramonlsouza Jun 30, 2026
d8a752a
bump Hasura version from 2.48.14 to 2.49.3
gustavotrott Jul 1, 2026
e08b554
Merge pull request #25327 from ramonlsouza/i-25177-p3
ramonlsouza Jul 1, 2026
ec88a83
Merge pull request #25349 from gustavotrott/hasura-2.49.3
ramonlsouza Jul 1, 2026
cee353b
fix(quick-poll): keep parenthetical text in Smart Slides poll questio…
Tainan404 Jul 1, 2026
c668458
chore: BigBlueButton release version to 3.0.32
ramonlsouza Jul 1, 2026
6b5dbca
Merge branch 'v3.0.x-release' into v3.0.x-develop
ramonlsouza Jul 1, 2026
af33e91
update export-annotations deps
ramonlsouza Jul 1, 2026
adb2068
fix(bbb-export-annotations): rasterize background slides to prevent O…
imdt-claudiop Jul 1, 2026
219a10d
refactor(bbb-export-annotations): rasterize the already-validated sli…
imdt-claudiop Jul 2, 2026
ca8f7e9
refactor(bbb-export-annotations): move regression tests to a dedicate…
imdt-claudiop Jul 2, 2026
a474efe
Merge pull request #25354 from imdt-claudiop/fix/odf-export-crop-2530…
TiagoJacobs Jul 2, 2026
0491a19
Merge remote-tracking branch 'upstream/v3.0.x-develop' into export-an
ramonlsouza Jul 2, 2026
52c89ec
update bbb-shared-notes-server dependencies
ramonlsouza Jul 2, 2026
8556124
Merge pull request #25353 from ramonlsouza/export-an
ramonlsouza Jul 2, 2026
be8f183
Merge pull request #25301 from bigbluebutton/dependabot/npm_and_yarn/…
ramonlsouza Jul 2, 2026
9a1f343
Merge pull request #25302 from bigbluebutton/dependabot/npm_and_yarn/…
ramonlsouza Jul 2, 2026
9c4f7a6
Merge pull request #25341 from bigbluebutton/dependabot/npm_and_yarn/…
ramonlsouza Jul 2, 2026
c558857
Merge pull request #25356 from ramonlsouza/up-shared-ns
ramonlsouza Jul 2, 2026
1f7bcb8
[update-sdk-version-0.0.103] update SDK version to 0.0.103
GuiLeme Jul 3, 2026
d117978
Merge pull request #25365 from GuiLeme/update-sdk-version-0.0.103
ramonlsouza Jul 3, 2026
b24d47d
feat(plugins): support configurable button styles
germanocaumo Jun 2, 2026
fce50d5
fix(plugins): preserve nav bar plugin button defaults
germanocaumo Jun 4, 2026
e3984d6
fix(plugins): use action bar button labels
germanocaumo Jun 8, 2026
9cb82f8
Merge pull request #25214 from germanocaumo/plugin-button-props
lfzawacki Jul 3, 2026
05b600d
build(deps): bump ch.qos.logback:logback-core in /bbb-recording-imex …
dependabot[bot] Jul 6, 2026
c18d465
build(deps): bump js-yaml in /bbb-learning-dashboard (#25369)
dependabot[bot] Jul 6, 2026
fd847d8
build(deps-dev): bump js-yaml in /bigbluebutton-tests/playwright (#25…
dependabot[bot] Jul 6, 2026
6a12bd7
build(deps): bump concurrent-ruby in /record-and-playback/core (#25307)
dependabot[bot] Jul 6, 2026
ca46266
build(deps): bump launch-editor in /bbb-learning-dashboard (#25295)
dependabot[bot] Jul 6, 2026
36699d8
build(deps): bump launch-editor from 2.12.0 to 2.14.1 in /docs (#25296)
dependabot[bot] Jul 6, 2026
d6bd7fa
fix(recording): Ruby 3.2 File.exists? deprecation in BigBlueButton re…
sanduhrs Jul 6, 2026
082d989
Update deploy.sh (#25372)
hiroshisuga Jul 6, 2026
ddeb4f3
build(deps): bump jwt from 2.5.0 to 2.10.3 in /record-and-playback/co…
dependabot[bot] Jul 6, 2026
9ffa172
feat(shared-notes): markdown export, init-from-markdown, and import m…
imdt-claudiop Jul 6, 2026
d7f769d
test(shared-notes): cover markdown export, init-from-markdown, and im…
imdt-claudiop Jul 6, 2026
c7caec6
harden shared-notes initial-content URL fetch
imdt-claudiop Jul 7, 2026
e0e78ed
fix(document): add --build for development scripts of bbb-web (#25379)
hiroshisuga Jul 7, 2026
83f698e
feat(shared-notes): add file upload to the Markdown import modal
imdt-claudiop Jul 7, 2026
1e6396a
feat(shared-notes): choose Append or Replace when importing Markdown
imdt-claudiop Jul 7, 2026
1a161d1
fix(shared-notes): satisfy tsc and eslint in Markdown import modal
imdt-claudiop Jul 7, 2026
fa64500
feat(shared-notes): reorder Markdown import first and make Markdown i…
imdt-claudiop Jul 8, 2026
6ab8a31
fix(shared-notes): add Markdown import/export flags to SharedNotes type
imdt-claudiop Jul 8, 2026
1351f23
fix(html5): add real Panopto player to external video share
imdt-claudiop Jul 8, 2026
e1ef07d
fix(html5): address review feedback on Panopto player
imdt-claudiop Jul 8, 2026
8440486
Merge pull request #2 from imdt-claudiop/feat/shared-notes-markdown-u…
imdt-claudiop Jul 8, 2026
0d23b2f
refactor(html5): extract shared getSDK util + harden Panopto URL vali…
imdt-claudiop Jul 8, 2026
719e40b
fix(html5): handle concurrent getSDK failures + accept Panopto URLs w…
imdt-claudiop Jul 8, 2026
fe312b6
fix(poll): drop out-of-range answerIds to avoid log noise (#25388)
imdt-claudiop Jul 8, 2026
42c5ec5
build(deps-dev): bump form-data in /bbb-graphql-client-test (#25377)
dependabot[bot] Jul 8, 2026
bba212d
fix(bbb-web): Handle Null Meeting IDs on IsMeetingRunning Requests (#…
paultrudel Jul 8, 2026
db42bf2
fix(html5): prevent crash from browser auto-translation
prlanzarin Jul 3, 2026
e81e9df
fix(video): never let the grid overflow tile consume a camera slot
prlanzarin Jul 3, 2026
e1225f9
test(playwright): support create modules in the POST body
prlanzarin Jul 3, 2026
492f511
build(ci): allow client settings override on create for tests
prlanzarin Jul 3, 2026
d05f221
fix(video): recompute the grid template when the overflow tile toggles
prlanzarin Jul 3, 2026
f1f3915
test(video): cover grid overflow camera precedence, count and geometry
prlanzarin Jul 3, 2026
03144b4
refactor(html5): drop redundant PanoptoPlayer.canPlay in url validation
imdt-claudiop Jul 8, 2026
5d8d877
test(shared-notes): cover the Markdown import cancel path
imdt-claudiop Jul 9, 2026
2d3c756
fix(video-provider): preview real user avatars in the camera overflow…
AtilaU19 Jul 3, 2026
c140899
fix(video-provider): include off-page webcam users in the overflow pr…
AtilaU19 Jul 7, 2026
84c9275
fix(video-provider): show the replaced avatar in the overflow preview
AtilaU19 Jul 8, 2026
6be752f
add missing color
ramonlsouza Jul 9, 2026
636135a
Merge pull request #25389 from imdt-claudiop/fix/issue-25384-panopto-…
antobinary Jul 9, 2026
5afcf65
fix(shared-notes): default Markdown menu options to false on 3.0
imdt-claudiop Jul 9, 2026
0888767
Merge pull request #25391 from ramonlsouza/bp-25371
ramonlsouza Jul 9, 2026
1be430d
Merge pull request #25394 from ramonlsouza/bp-25370
ramonlsouza Jul 9, 2026
aa40524
Merge remote-tracking branch 'upstream/v3.0.x-develop' into bp-25362
ramonlsouza Jul 9, 2026
c6fb2fa
fix(shared-notes): guard Markdown import parse and document URL fetch…
imdt-claudiop Jul 9, 2026
3f34729
Merge pull request #25392 from ramonlsouza/bp-25362
ramonlsouza Jul 9, 2026
4ad56e1
fix(bbb-web): render a response when insertDocument body has no prese…
germanocaumo Jul 9, 2026
4520278
refactor(shared-notes): clear SonarCloud smells on the Markdown impor…
imdt-claudiop Jul 9, 2026
75a871e
fix(html5): re-center microphone glyph in audio modal
imdt-claudiop Jul 9, 2026
cc0532c
fix(html5): increase mic glyph nudge to -0.14em per review
imdt-claudiop Jul 10, 2026
234c17b
fix(html5): scale mic glyph to match headphone vertical footprint
imdt-claudiop Jul 12, 2026
bd7b116
fix(shared-notes): guard markdown seeding like the JSON path
imdt-claudiop Jul 12, 2026
91a7baa
fix(html5): address Copilot review on mic glyph selector and comment
imdt-claudiop Jul 13, 2026
ceb592d
fix(html5): drop redundant display:inline-block on mic glyph
imdt-claudiop Jul 13, 2026
9720ff8
Merge pull request #25350 from Tainan404/i-25320
ramonlsouza Jul 14, 2026
183af81
docs: Enhance document upload parameters in API docs (#25413)
samuelwei Jul 14, 2026
cc5441b
Merge pull request #25396 from imdt-claudiop/fix/audio-modal-mic-icon…
TiagoJacobs Jul 14, 2026
09b3d1a
fix: allow negative timeSync skew to correct client-ahead clock (#25311)
imdt-claudiop Jul 15, 2026
61c9053
fix(core): API parameter downloadable is not working (#25414)
ramonlsouza Jul 15, 2026
db69a00
fix(html5): retry locale fetch on transient network failure (#25423)
imdt-claudiop Jul 15, 2026
5de2ca0
Merge pull request #25373 from imdt-claudiop/feat/shared-notes-markdown
antobinary Jul 16, 2026
69fa77a
docs: clarify allowOverrideClientSettingsOnCreateCall is a server set…
antobinary Jul 16, 2026
b3db683
fix(shared-notes): show unread indicator for BlockNote notes
imdt-claudiop Jun 11, 2026
5110326
test(shared-notes): cover BlockNote unread indicator lifecycle
imdt-claudiop Jun 11, 2026
771cee6
chore: Update BigBlueButton release version to 3.0.33
antobinary Jul 17, 2026
e944de7
test(recording): use BlockNote editor for shared-notes recording step
antobinary Jul 17, 2026
7780ba2
Merge branch 'v3.0.x-develop' of github.com:bigbluebutton/bigbluebutt…
lfzawacki Jul 17, 2026
e53cbd2
Merge branch 'v4.0.x-develop' into v4.0.x-develop
lfzawacki Jul 17, 2026
9d709d9
build(bbb-web): pin tomcat-embed to 10.1.56
antobinary Jul 17, 2026
4414cff
build(bbb-web): update Spring Boot to 3.5.16
antobinary Jul 17, 2026
9fd95ea
chore(akka): bump shared JVM dependency versions
antobinary Jul 17, 2026
7a54a49
chore(bbb-web): bump dependencies
antobinary Jul 17, 2026
d112d47
Merge pull request #25451 from antobinary/fix-recording-e2e-blocknote
ramonlsouza Jul 20, 2026
af4083b
fix(chat): render private chat previews from the chats subscription
imdt-claudiop Jul 20, 2026
e720e0c
Fix(blocknote): shared notes unread indicator (#25269)
antobinary Jul 20, 2026
6900df9
Merge pull request #25457 from antobinary/port-core-deps
antobinary Jul 20, 2026
d6c1582
use constants for test delay/timeout
ramonlsouza Jul 20, 2026
00b1831
Merge pull request #25467 from Tainan404/fix-25416-private-chat-previ…
ramonlsouza Jul 20, 2026
058c644
docs: drop 3.0 portion of new-features.md added during merge
antobinary Jul 20, 2026
0884117
Merge branch 'v4.0.x-develop' into v4.0.x-develop
lfzawacki Jul 20, 2026
415a93e
fix(merge): remaining post merge errors
lfzawacki Jul 20, 2026
26f59dd
fix(tsc): Fix tsc errors after merge
lfzawacki Jul 20, 2026
5840bc2
fix(test): restore BlockNote shared-notes helpers dropped in 3.0->4.0…
antobinary Jul 21, 2026
b01a012
fix(document-title): use titlePrivateToUser for the private-chat title
antobinary Jul 21, 2026
da3dc33
test(document-title): partially adapt notes/poll/settings specs to th…
antobinary Jul 21, 2026
4cf89d8
fix(document-title): wire showUploadPresentationView so the Upload Pr…
antobinary Jul 21, 2026
e5de07b
test(document-title): finish the 4.0 UI adaptation for active-views a…
antobinary Jul 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion akka-bbb-apps/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console",
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports")

Seq(Revolver.settings: _*)
lazy val bbbAppsAkka = (project in file(".")).settings(name := "bbb-apps-akka", libraryDependencies ++= Dependencies.runtime).settings(compileSettings)
lazy val bbbAppsAkka = (project in file(".")).settings(name := "bbb-apps-akka", libraryDependencies ++= Dependencies.runtime, dependencyOverrides ++= Dependencies.overrides).settings(compileSettings)

// See https://github.com/scala-ide/scalariform
// Config file is in ./.scalariform.conf
Expand Down
2 changes: 2 additions & 0 deletions akka-bbb-apps/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ echo ''
echo '----------------'
echo 'bbb-apps-akka updated'

sudo systemctl enable bbb-apps-akka.service

sudo service bbb-apps-akka start
echo 'starting service bbb-apps-akka'
27 changes: 22 additions & 5 deletions akka-bbb-apps/project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@ object Dependencies {
val pekkoVersion = "1.0.1"
val pekkoHttpVersion = "1.0.0"
val gson = "2.8.9"
val jackson = "2.13.5"
val logback = "1.2.13"
val jackson = "2.18.9"
val netty = "4.1.135.Final"
val logback = "1.5.38"
val slf4j = "2.0.17"
val quicklens = "1.7.5"
val spray = "1.3.6"
val semver = "0.10.2"
val commonmark = "0.27.0"

// Apache Commons
val lang = "3.12.0"
val lang = "3.18.0"
val codec = "1.15"
val httpcomponents = "4.5.14"

Expand All @@ -32,14 +34,14 @@ object Dependencies {

// Database
val slick = "3.4.1"
val postgresql = "42.5.0"
val postgresql = "42.7.13"
val slickPg = "0.21.1"

// Test
val scalaTest = "3.2.11"
val mockito = "2.23.0"
val akkaTestKit = "2.6.0"
val jacksonDataFormat = "2.13.5"
val jacksonDataFormat = "2.18.9"
}

object Compile {
Expand Down Expand Up @@ -117,4 +119,19 @@ object Dependencies {
Compile.slickPgSprayJson,
Compile.postgresql,
Compile.jacksonDataFormat) ++ testing

// Pin transitively-pulled artifacts to fixed releases; keep the jackson suite aligned.
val overrides = Seq(
"com.fasterxml.jackson.core" % "jackson-databind" % Versions.jackson,
"com.fasterxml.jackson.core" % "jackson-core" % Versions.jackson,
"com.fasterxml.jackson.core" % "jackson-annotations" % Versions.jackson,
"io.netty" % "netty-handler" % Versions.netty,
"io.netty" % "netty-codec" % Versions.netty,
"io.netty" % "netty-common" % Versions.netty,
"io.netty" % "netty-buffer" % Versions.netty,
"io.netty" % "netty-transport" % Versions.netty,
"io.netty" % "netty-resolver" % Versions.netty,
// logback 1.5.x is an slf4j-2.x provider; pin slf4j-api 2.x so the
// ServiceLoader binding resolves (pekko-slf4j is runtime-compatible).
"org.slf4j" % "slf4j-api" % Versions.slf4j)
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,17 @@ object PadslHdlrHelpers {
}

def broadcastBNSharedNotesCreateCmdMsg(
outGW: OutMsgRouter,
meetingId: String,
externalId: String,
model: String,
sharedNotesInitialContentJson: Vector[AnyRef]
outGW: OutMsgRouter,
meetingId: String,
externalId: String,
model: String,
sharedNotesInitialContentJson: Vector[AnyRef],
sharedNotesInitialContentMarkdown: String
): Unit = {
val routing = collection.immutable.HashMap("sender" -> "bbb-apps-akka")
val envelope = BbbCoreEnvelope(BNSharedNotesCreateCmdMsg.NAME, routing)
val header = BbbCoreHeaderWithMeetingId(BNSharedNotesCreateCmdMsg.NAME, meetingId)
val body = BNSharedNotesCreateCmdMsgBody(externalId, model, sharedNotesInitialContentJson)
val body = BNSharedNotesCreateCmdMsgBody(externalId, model, sharedNotesInitialContentJson, sharedNotesInitialContentMarkdown)
val event = BNSharedNotesCreateCmdMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ import org.bigbluebutton.core.running.OutMsgRouter

object PollHdlrHelpers {

// Selects the answer ids that will actually be recorded for a poll vote.
//
// - A single-response question keeps at most the first requested id; a
// multi-response question keeps every distinct requested id.
// - Out-of-range ids (negative, or >= the number of options) are dropped so a
// malformed vote can neither crash the meeting actor via the indexed answer
// access that follows nor violate the poll_response foreign key on
// persistence. Invalid votes are silently ignored.
//
// validAnswerIds is the range of option indices for the question (empty when
// the question has no answers), so an empty range drops every requested id.
def selectValidAnswerIds(requestedAnswerIds: Seq[Int], multiResponse: Boolean, validAnswerIds: Range): Seq[Int] = {
val deduped =
if (!multiResponse && requestedAnswerIds.length > 1) {
Seq(requestedAnswerIds.head)
} else {
requestedAnswerIds.distinct
}
deduped.filter(validAnswerIds.contains)
}

def broadcastPollUpdatedEvent(outGW: OutMsgRouter, meetingId: String, userId: String, pollId: String, poll: SimplePollResultOutVO): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
val envelope = BbbCoreEnvelope(PollUpdatedEvtMsg.NAME, routing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ trait RespondToPollReqMsgHdlr {
if (poll.stopped) {
log.info("Ignoring vote from user {} because poll {} is already finished in meeting {}", msg.header.userId, msg.body.pollId, msg.header.meetingId)
} else {
val answers = {
if (!poll.questions(0).multiResponse && msg.body.answerIds.length > 1) {
Seq(msg.body.answerIds.head)
} else {
msg.body.answerIds.distinct
}
}
val question = poll.questions.headOption
val answerList = question.flatMap(_.answers)
// Valid answer ids are the option indices of the poll's question. Any id
// outside this range is a malformed/out-of-range vote.
val validAnswerIds = answerList.map(_.indices).getOrElse(0 until 0)

val answers = PollHdlrHelpers.selectValidAnswerIds(
msg.body.answerIds, question.exists(_.multiResponse), validAnswerIds
)

for {
(pollId: String, updatedPoll: SimplePollResultOutVO) <- Polls.handleRespondToPollReqMsg(msg.header.userId, poll.id,
Expand All @@ -34,8 +36,9 @@ trait RespondToPollReqMsgHdlr {
PollHdlrHelpers.broadcastPollUpdatedEvent(bus.outGW, liveMeeting.props.meetingProp.intId, msg.header.userId, pollId, updatedPoll)
for {
answerId <- answers
options <- answerList
} yield {
val answerText = poll.questions(0).answers.get(answerId).key
val answerText = options(answerId).key
PollHdlrHelpers.broadcastUserRespondedToPollRecordMsg(bus.outGW, liveMeeting.props.meetingProp.intId, msg.header.userId, pollId, answerId, answerText, poll.isSecret)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import org.bigbluebutton.core.models.PresentationInPod
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.core2.message.senders.MsgBuilder

import java.io.File
import java.net.URI
import java.time.{Instant, Duration}

trait PresentationConversionCompletedSysPubMsgHdlr {
Expand Down Expand Up @@ -58,6 +60,12 @@ trait PresentationConversionCompletedSysPubMsgHdlr {
pods = pods.addPresentationToPod(pod.id, presWithConvertedName)

PresPresentationDAO.updatePages(presWithConvertedName)
if (pres.downloadable) {
val originalFilename = new URI(null, null, pres.name, null).getRawPath
val originalFileURI = List("presentation", "download", meetingId,
s"${pres.id}?presFilename=${pres.id}.${originalDownloadableExtension}&filename=$originalFilename").mkString("", File.separator, "")
PresPresentationDAO.updateDownloadUri(pres.id, originalFileURI)
}
if(pres.current) {
val notifyEvent = MsgBuilder.buildNotifyAllInMeetingEvtMsg(
meetingId,
Expand Down Expand Up @@ -93,4 +101,3 @@ trait PresentationConversionCompletedSysPubMsgHdlr {

}
}

Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ object SharedNotesRevDAO {
def insertNextRev(meetingId: String, sharedNotesExtId: String, userId: String) = {
DatabaseConnection.enqueue(
sqlu"""
insert into "sharedNotes_rev"("meetingId", "sharedNotesExtId", "userId", "rev")
insert into "sharedNotes_rev"("meetingId", "sharedNotesExtId", "userId", "rev", "createdAt")
select
${meetingId} as "meetingId",
${sharedNotesExtId} as "sharedNotesExtId",
Expand All @@ -58,7 +58,8 @@ object SharedNotesRevDAO {
from "sharedNotes_rev"
where "meetingId" = ${meetingId}
and "sharedNotesExtId" = ${sharedNotesExtId}
),0) + 1 as "rev"
),0) + 1 as "rev",
current_timestamp as "createdAt"
"""
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,8 @@ class MeetingActor(
} else {
PadslHdlrHelpers.broadcastBNSharedNotesCreateCmdMsg(
outGW, liveMeeting.props.meetingProp.intId,
sharedNotesPadId, sharedNotesPadId, liveMeeting.props.meetingProp.sharedNotesInitialContentJson
sharedNotesPadId, sharedNotesPadId, liveMeeting.props.meetingProp.sharedNotesInitialContentJson,
liveMeeting.props.meetingProp.sharedNotesInitialContentMarkdown
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ class AnalyticsActor(val includeChat: Boolean) extends Actor with ActorLogging {

// Breakouts
case m: CreateBreakoutRoomsCmdMsg => logMessage(msg)
case m: ChangeUserBreakoutReqMsg => logMessage(msg)

case _ => // ignore message
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.bigbluebutton.core.apps.polls

import org.scalatest.flatspec.AnyFlatSpec

// Exercises the answer-id bounds filter that keeps a malformed poll vote from
// reaching the indexed answer access in the handler (which would crash the
// meeting actor) or the poll_response foreign key on persistence. The logic
// lives in the PollHdlrHelpers object so it can be tested in isolation, without
// standing up a LiveMeeting / MessageBus / poll fixtures.
//
// NOTE: extends AnyFlatSpec directly rather than the shared UnitSpec, which
// currently does not compile against the resolved ScalaTest 3.2.x (UnitSpec
// still imports the pre-3.2 org.scalatest.FlatSpec / Matchers packages). Same
// choice WhiteboardModelSpec made.
class PollHdlrHelpersSpec extends AnyFlatSpec {

import PollHdlrHelpers.selectValidAnswerIds

// A two-option question: valid indices are 0 and 1.
private val validAnswerIds = 0 until 2

it should "drop an id past the last option (999)" in {
assert(selectValidAnswerIds(Seq(999), multiResponse = false, validAnswerIds) == Seq.empty)
}

it should "drop a negative id (-1)" in {
assert(selectValidAnswerIds(Seq(-1), multiResponse = false, validAnswerIds) == Seq.empty)
}

it should "drop Int.MaxValue without an index-out-of-bounds crash" in {
assert(selectValidAnswerIds(Seq(2147483647), multiResponse = false, validAnswerIds) == Seq.empty)
}

it should "keep a valid id (0)" in {
assert(selectValidAnswerIds(Seq(0), multiResponse = false, validAnswerIds) == Seq(0))
}

it should "return empty for an empty vote (no-op)" in {
assert(selectValidAnswerIds(Seq.empty, multiResponse = false, validAnswerIds) == Seq.empty)
}

it should "keep every valid id when the question is multi-response" in {
assert(selectValidAnswerIds(Seq(0, 1), multiResponse = true, validAnswerIds) == Seq(0, 1))
}

it should "keep only the first id when the question is single-response" in {
assert(selectValidAnswerIds(Seq(0, 1), multiResponse = false, validAnswerIds) == Seq(0))
}

it should "drop a single-response vote whose first id is out of range" in {
// Single-response keeps only the head, then bounds-filters it: an
// out-of-range head leaves nothing, it does not fall through to a later id.
assert(selectValidAnswerIds(Seq(999, 0), multiResponse = false, validAnswerIds) == Seq.empty)
}

it should "drop every id when the question has no answers (empty valid range)" in {
// Mirrors the handler's answers=None path: with no answer options the valid
// range is empty, so nothing survives the filter.
val noOptions = 0 until 0
assert(selectValidAnswerIds(Seq(0, 1, 999), multiResponse = true, noOptions) == Seq.empty)
}

it should "collapse duplicate valid ids on a multi-response vote" in {
assert(selectValidAnswerIds(Seq(1, 1, 0), multiResponse = true, validAnswerIds) == Seq(1, 0))
}
}
2 changes: 1 addition & 1 deletion akka-bbb-fsesl/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "html", "console",
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-h", "target/scalatest-reports")

Seq(Revolver.settings: _*)
lazy val bbbFseslAkka = (project in file(".")).settings(name := "bbb-fsesl-akka", libraryDependencies ++= Dependencies.runtime).settings(compileSettings)
lazy val bbbFseslAkka = (project in file(".")).settings(name := "bbb-fsesl-akka", libraryDependencies ++= Dependencies.runtime, dependencyOverrides ++= Dependencies.overrides).settings(compileSettings)

// See https://github.com/scala-ide/scalariform
// Config file is in ./.scalariform.conf
Expand Down
24 changes: 22 additions & 2 deletions akka-bbb-fsesl/project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ object Dependencies {
// Libraries
val pekkoVersion = "1.0.1"
val pekkoHttpVersion = "1.0.0"
val logback = "1.2.13"
val logback = "1.5.38"
val jackson = "2.18.9"
val netty = "4.1.135.Final"
val slf4j = "2.0.17"

// Apache Commons
val lang = "3.12.0"
val lang = "3.18.0"
val codec = "1.15"

// BigBlueButton
Expand Down Expand Up @@ -83,4 +86,21 @@ object Dependencies {
Compile.bbbFseslClient,
Compile.pekkoHttp,
Compile.pekkoHttpSprayJson) ++ testing

// Pin transitively-pulled artifacts to fixed releases; keep the jackson suite aligned.
val overrides = Seq(
"com.fasterxml.jackson.core" % "jackson-databind" % Versions.jackson,
"com.fasterxml.jackson.core" % "jackson-core" % Versions.jackson,
"com.fasterxml.jackson.core" % "jackson-annotations" % Versions.jackson,
"com.fasterxml.jackson.dataformat" % "jackson-dataformat-yaml" % Versions.jackson,
"com.fasterxml.jackson.module" %% "jackson-module-scala" % Versions.jackson,
"io.netty" % "netty-handler" % Versions.netty,
"io.netty" % "netty-codec" % Versions.netty,
"io.netty" % "netty-common" % Versions.netty,
"io.netty" % "netty-buffer" % Versions.netty,
"io.netty" % "netty-transport" % Versions.netty,
"io.netty" % "netty-resolver" % Versions.netty,
// logback 1.5.x is an slf4j-2.x provider; pin slf4j-api 2.x so the
// ServiceLoader binding resolves (pekko-slf4j is runtime-compatible).
"org.slf4j" % "slf4j-api" % Versions.slf4j)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ case class MeetingProp(
intId: String,
meetingCameraCap: Int,
sharedNotesInitialContentJson: Vector[AnyRef],
sharedNotesInitialContentMarkdown: String = "",
sharedNotesEditor: String,
maxPinnedCameras: Int,
cameraBridge: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ case class PadCreateReqMsgBody(externalId: String, name: String)
// apps -> shared-notes-server
object BNSharedNotesCreateCmdMsg { val NAME = "BNSharedNotesCreateCmdMsg" }
case class BNSharedNotesCreateCmdMsg(header: BbbCoreHeaderWithMeetingId, body: BNSharedNotesCreateCmdMsgBody) extends BbbCoreMsg
case class BNSharedNotesCreateCmdMsgBody(externalId: String, model: String, initialContentJson: Vector[AnyRef])
case class BNSharedNotesCreateCmdMsgBody(externalId: String, model: String, initialContentJson: Vector[AnyRef], initialContentMarkdown: String = "")

// shared-notes-server -> apps
object BNSharedNotesCreatedEvtMsg { val NAME = "BNSharedNotesCreatedEvtMsg" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public class ApiParams {
public static final String ALLOW_START_STOP_RECORDING = "allowStartStopRecording";
public static final String SHARED_NOTES_EDITOR = "sharedNotesEditor";
public static final String SHARED_NOTES_INITIAL_CONTENT_JSON_URL = "sharedNotesInitialContentJsonUrl";
public static final String SHARED_NOTES_INITIAL_CONTENT_MARKDOWN = "sharedNotesInitialContentMarkdown";
public static final String SHARED_NOTES_INITIAL_CONTENT_MARKDOWN_URL = "sharedNotesInitialContentMarkdownUrl";
public static final String ATTENDEE_PW = "attendeePW";
public static final String AUTO_START_RECORDING = "autoStartRecording";
public static final String BANNER_COLOR = "bannerColor";
Expand Down
Loading
Loading