Skip to content

feat: BigBlueButton video conferencing integration#29434

Closed
q404365631 wants to merge 2 commits into
calcom:mainfrom
q404365631:feat/bigbluebutton-integration
Closed

feat: BigBlueButton video conferencing integration#29434
q404365631 wants to merge 2 commits into
calcom:mainfrom
q404365631:feat/bigbluebutton-integration

Conversation

@q404365631
Copy link
Copy Markdown

Description

Add BigBlueButton as a conferencing app in the app store. This integration enables users to create and manage BBB meetings directly from Cal.diy.

Closes #1985

Changes

New Files (18)

  • packages/app-store/bigbluebuttonvideo/ - Complete app with metadata, Zod schemas, API client, tests
  • apps/web/components/apps/bigbluebuttonvideo/Setup.tsx - Setup form with i18n support
  • apps/web/components/apps/appsWithSetupForm.ts - Setup form routing system for non-OAuth apps

Modified Files (10)

  • AppSetupPage.tsx - Added BBB dynamic import
  • AppCard.tsx - Added setup form check in handleAppInstall
  • getServerSideProps.ts - Added setup form redirect for credential-less apps
  • i18n common.json - 6 BBB translation keys
  • 6x .generated.ts - Added BBB entries to all codegen files

Architecture

  • Follows existing Jitsi conferencing pattern
  • BBB API client with SHA1 checksum authentication + XML parsing (fast-xml-parser)
  • Symmetric credential encryption via CALENDSO_ENCRYPTION_KEY
  • Full meeting lifecycle: create, update, delete, getRecordings, getRecordingDownloadLink
  • 18 tests with comprehensive error path coverage (HTTP errors, malformed XML, timeout, credential failures)
  • Team and individual installation support with admin access verification

Testing

  • �bbClient.test.ts: 12 tests (checksum, URL building, XML parsing, HTTP errors, timeout)
  • VideoApiAdapter.test.ts: 6 tests (create, update, availability, decryption failures, missing env vars)

/claim #1985

Add BigBlueButton as a conferencing app in the app store. This integration
enables users to create and manage BBB meetings directly from Cal.com.

Key features:
- BBB API client with SHA1 checksum authentication
- Symmetric credential encryption via CALENDSO_ENCRYPTION_KEY
- Full meeting lifecycle: create, update, delete, getRecordings
- Setup form for server URL and shared secret collection
- Comprehensive test suite with error path coverage (18 tests)
- Support for team and individual installation

Architecture follows the existing Jitsi conferencing pattern with:
- VideoApiAdapter interface implementation
- Zod schema validation for credentials
- appsWithSetupForm routing system for non-OAuth apps
- Proper admin access verification for team installs

Closes calcom#1985
@github-actions
Copy link
Copy Markdown
Contributor

Welcome to Cal.diy, @q404365631! Thanks for opening this pull request.

A few things to keep in mind:

  • This is Cal.diy, not Cal.com. Cal.diy is a community-driven, fully open-source fork of Cal.com licensed under MIT. Your changes here will be part of Cal.diy — they will not be deployed to the Cal.com production app.
  • Please review our Contributing Guidelines if you haven't already.
  • Make sure your PR title follows the Conventional Commits format.

A maintainer will review your PR soon. Thanks for contributing!

@github-actions github-actions Bot added $50 app-store area: app store, apps, calendar integrations, google calendar, outlook, lark, apple calendar community Created by Linear-GitHub Sync consumer ✨ feature New feature or request 💎 Bounty A bounty on Algora.io 🙋🏻‍♂️help wanted Help from the community is appreciated labels May 24, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 74ee44e6-363b-4d62-9bb3-8c5b5adfdbb8

📥 Commits

Reviewing files that changed from the base of the PR and between 9e9afec and 638eef4.

📒 Files selected for processing (6)
  • apps/web/components/apps/bigbluebuttonvideo/Setup.tsx
  • packages/app-store/bigbluebuttonvideo/api/add.ts
  • packages/app-store/bigbluebuttonvideo/lib/bbbClient.test.ts
  • packages/app-store/bigbluebuttonvideo/lib/bbbClient.ts
  • packages/app-store/bigbluebuttonvideo/zod.ts
  • packages/i18n/locales/en/common.json
💤 Files with no reviewable changes (1)
  • packages/app-store/bigbluebuttonvideo/lib/bbbClient.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/app-store/bigbluebuttonvideo/zod.ts
  • apps/web/components/apps/bigbluebuttonvideo/Setup.tsx
  • packages/app-store/bigbluebuttonvideo/lib/bbbClient.ts
  • packages/app-store/bigbluebuttonvideo/api/add.ts

📝 Walkthrough

Walkthrough

This PR introduces BigBlueButton video conferencing support to Cal.com. The implementation adds a low-level BBB API client with request signing and XML parsing, registers the app in the app store with metadata and schemas, provides a backend API route for validating and persisting BBB credentials, implements a VideoApiAdapter for meeting lifecycle operations, and wires a client-side setup form into the app installation flow. The setup form collects server URL and shared secret credentials, validates them against the BBB API, and encrypts them before storage.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: BigBlueButton video conferencing integration' clearly summarizes the main change—adding BigBlueButton as a new conferencing app integration to the platform.
Description check ✅ Passed The description is directly related to the changeset, detailing the addition of BigBlueButton integration, modified and new files, architecture, and testing coverage.
Linked Issues check ✅ Passed The PR fully implements the BigBlueButton integration requirements from issue #1985: API integration, credential validation/encryption, team/individual install support, checksum authentication, XML parsing, and comprehensive testing.
Out of Scope Changes check ✅ Passed All changes are within scope of adding BigBlueButton integration: new app package files, setup form, routing logic, API handlers, i18n keys, and schema registrations are all necessary for the feature.
Docstring Coverage ✅ Passed Docstring coverage is 91.67% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Nitpick comments (6)
packages/app-store/bigbluebuttonvideo/api/add.ts (1)

13-18: ⚡ Quick win

Trim “what” comments and keep only rationale (“why”) comments.

Most comments in this handler restate the code flow. Please remove or rewrite them to capture non-obvious decisions only.

As per coding guidelines: "Only add code comments that explain why, not what" and "Never add comments that simply restate what the code does".

Also applies to: 26-26, 46-46, 51-51, 61-61, 70-70, 81-81

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app-store/bigbluebuttonvideo/api/add.ts` around lines 13 - 18, The
comments in the BigBlueButton installation handler
(packages/app-store/bigbluebuttonvideo/api/add.ts — the POST handler function)
are “what” comments that merely restate code flow; remove or replace them so
only non-obvious rationale remains (explain why decisions were made, e.g., why
you validate with getMeetings, why you encrypt the secret, any security
assumptions or edge cases), and delete redundant inline comments around the
credential validation, encryption/storage, and redirect logic (currently near
the credential parsing, getMeetings call, encryption step, and redirect
response). Ensure any retained comments explain intent or trade-offs rather than
restating actions.
packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.ts (1)

17-24: ⚡ Quick win

Use ErrorWithCode for credential/config validation failures.

This helper throws plain Error for missing env/config problems, which makes the adapter inconsistent with the repo’s non-tRPC error contract. Please switch these branches to ErrorWithCode so callers can handle credential/setup failures predictably.

As per coding guidelines "Use ErrorWithCode for errors in non-tRPC files (services, repositories, utilities); use TRPCError only in tRPC routers".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.ts` around lines 17
- 24, Replace the plain Error throws in VideoApiAdapter.ts with the project's
ErrorWithCode so credential/config validation failures follow the repo's
non-tRPC error contract: where encryptionKey is validated (the branch throwing
"CALENDSO_ENCRYPTION_KEY environment variable is not set.") and where
credentialKey type is checked (the branch throwing "Invalid credential key
format."), throw new ErrorWithCode with an appropriate code (e.g., "BAD_REQUEST"
or "INVALID_CREDENTIALS") and descriptive message; also add the ErrorWithCode
import at the top of the file if not present.
apps/web/components/apps/bigbluebuttonvideo/Setup.tsx (1)

20-20: ⚡ Quick win

Remove “what” comments in the component.

These comments explain obvious behavior and should be removed (or replaced with “why” context only).

As per coding guidelines, "Only add code comments that explain why, not what" and "Never add comments that simply restate what the code does."

Also applies to: 28-31

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/components/apps/bigbluebuttonvideo/Setup.tsx` at line 20, Remove the
comment(s) that state obvious facts (e.g. the /* 表单字段验证模式 */ and the similar
comments at lines 28-31) from the Setup component; if additional context is
needed, replace them with a brief "why" comment explaining intent or rationale
for the validation mode/behavior used in the Setup.tsx component (reference the
Setup component and any local validation-related variables/props to place the
why-comment).
apps/web/modules/apps/components/AppCard.tsx (1)

75-75: ⚡ Quick win

Remove the inline “what” comment above the setup-form branch.

The code is already self-explanatory; keep comments only for rationale that isn't obvious from control flow.

As per coding guidelines, "Only add code comments that explain why, not what" and "Never add comments that simply restate what the code does."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/modules/apps/components/AppCard.tsx` at line 75, Remove the
redundant inline “what” comment above the setup-form branch in the AppCard
component: open the AppCard component (symbol AppCard) and delete the
single-line Chinese comment that restates behavior for setup-form apps so only
necessary rationale comments remain, keeping the control flow self-explanatory.
apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts (1)

451-451: ⚡ Quick win

Drop the explanatory inline comment or rewrite as rationale.

This comment restates the code path; keep comments only when they explain non-obvious intent/trade-offs.

As per coding guidelines, "Only add code comments that explain why, not what" and "Never add comments that simply restate what the code does."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/lib/apps/installation/`[[...step]]/getServerSideProps.ts at line
451, The inline comment "// 无凭证且 app 需要 setup form 时,重定向到 setup 页面采集凭证" in
getServerSideProps is restating the code path; remove it or replace it with a
brief rationale explaining the non-obvious intent (e.g., why redirecting here is
required for UX/consistency or to avoid exposing partial app state). Locate the
comment near the getServerSideProps handler in
apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts and either
delete that line or swap it for a one-sentence "why" comment referencing the
redirect's purpose and any trade-offs (security/UX), not the "what".
apps/web/components/apps/appsWithSetupForm.ts (1)

1-5: ⚡ Quick win

Remove “what” comments or rewrite them to explain intent.

These comments currently restate behavior instead of rationale. Please remove them or rewrite to capture non-obvious design intent only.

As per coding guidelines, "Only add code comments that explain why, not what" and "Never add comments that simply restate what the code does."

Also applies to: 8-10, 15-18

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/components/apps/appsWithSetupForm.ts` around lines 1 - 5, The
top-of-file comment blocks are "what" comments that restate behavior; remove or
rewrite them to capture the rationale for the special-case list of app slugs
(i.e., why certain non-OAuth apps require a custom setup form and must follow
the setup flow instead of the auto-install flow). Update the comment(s) near the
list(s) in appsWithSetupForm.ts (and the similar blocks referenced around the
other comment ranges) to be terse and intent-focused: explain the non-obvious
design decision or constraint (e.g., credential storage semantics, security or
UX reasons, or upstream API differences) that necessitates using a setup form,
rather than describing the behavior itself. Ensure the new comment references
the list's purpose only in terms of the why, then remove any redundant
explanatory lines.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/components/apps/bigbluebuttonvideo/Setup.tsx`:
- Line 83: Replace the hardcoded placeholder
"https://your-bbb-server.com/bigbluebutton" with a translatable key: add e.g.
"bigbluebutton.serverPlaceholder": "https://your-bbb-server.com/bigbluebutton"
to packages/i18n/locales/en/common.json, then in
apps/web/components/apps/bigbluebuttonvideo/Setup.tsx use the i18n translator
(e.g. useTranslation or t already in scope) to render the placeholder via
t('bigbluebutton.serverPlaceholder') instead of the literal string so the UI
string is localizable.
- Around line 37-44: The formSchema zod validator is defined but not wired into
useForm, so client-side validation isn't applied; update the useForm call (the
one creating form in Setup.tsx) to pass a resolver using zodResolver(formSchema)
(ensure zodResolver is imported) so that form validation runs before onSubmit
and FormValues matches the schema.

In `@apps/web/lib/apps/installation/`[[...step]]/getServerSideProps.ts:
- Around line 452-455: The getCredential branch that checks if (!credentialId &&
!appMetadata.isOAuth) calls setupFormRedirectFor(parsedAppSlug) and returns
setupRedirect directly, which violates the declared return type Promise<{
credentialId: number | null; redirect?: RedirectResult }>; instead, change that
branch to return an object with credentialId: null and redirect: setupRedirect
(i.e., return { credentialId: null, redirect: setupRedirect }) so the function
signature is honored while preserving the redirect behavior.

In `@packages/app-store/bigbluebuttonvideo/api/add.ts`:
- Around line 77-79: Replace the two throws that use new Error(...) with
ErrorWithCode so error handling is deterministic: where the handler checks
alreadyInstalled and currently does throw new Error("Already installed"), change
it to throw new ErrorWithCode("Already installed", "CONFLICT"); and where
credential creation failure currently throws new Error("Unable to create
credential") change it to throw new ErrorWithCode("Unable to create credential",
"INTERNAL"). Also add the required import for ErrorWithCode from the project
error utility and preserve the original messages and surrounding logic in the
same function (the checks referencing alreadyInstalled and the credential
creation path).
- Around line 71-76: The Prisma queries currently materialize full credential
rows; change prisma.credential.findFirst (used to set alreadyInstalled) to
select only non-sensitive fields (e.g., select: { id: true }) so you only check
existence, and likewise change prisma.credential.create to return only
non-sensitive fields (e.g., select: { id: true }) so credential.key is not
materialized unnecessarily; update the calls referencing
prisma.credential.findFirst and prisma.credential.create accordingly.

In `@packages/app-store/bigbluebuttonvideo/lib/bbbClient.test.ts`:
- Around line 37-41: The test for buildSignedUrl contains contradictory
assertions: one expects the URL to end with an empty checksum ("...?checksum=")
while the other expects a 40-char checksum; remove the exact-match assertion and
keep a single, consistent check (e.g., use
expect(url).toMatch(/\/api\/getMeetings\?checksum=[0-9a-f]{40}$/)) so the test
verifies the URL path and a valid SHA-1 checksum produced by buildSignedUrl
rather than an empty checksum.

In `@packages/app-store/bigbluebuttonvideo/lib/bbbClient.ts`:
- Around line 91-103: The fetch call that sets response (inside the try block in
bbbClient.ts) can throw on network/abort errors and currently escapes; wrap the
await fetch(...) in a try/catch (keeping the existing finally that calls
clearTimeout(timeoutId)) and in the catch convert any thrown error into a
BbbApiError (e.g., new BbbApiError(error.message or a short description,
"bbb_network_error")), preserving original error details if possible (as cause
or included in the message) so callers always receive a BbbApiError instead of
raw exceptions; reference the existing symbols response, controller.signal,
timeoutId, and BbbApiError when making the change.
- Around line 51-53: The XML validation check in bbbClient.ts is inverted:
XMLValidator.validate(xmlResponse) returns true for valid XML and an error
object for invalid XML, so replace the current negated check with a proper
comparison (e.g., let validation = XMLValidator.validate(xmlResponse); if
(validation !== true) throw new BbbApiError("BBB returned a malformed XML
response.", "malformed_xml_response");) referencing XMLValidator.validate,
xmlResponse, and BbbApiError to locate the change.

In `@packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.ts`:
- Around line 86-95: The join URL for attendees is missing the required
BigBlueButton checksum—replace the direct buildUrl(...) usage in the
createMeeting and updateMeeting flows with the existing BBB signing utilities:
construct the same query string used for buildUrl (meetingID,
password/attendeePW, fullName) and pass it to buildChecksum or buildSignedUrl
together with bbbCredential.sharedSecret so the generated joinUrl includes the
checksum; update the call sites that currently call buildUrl(...) (referencing
buildUrl, meetingId, attendeePW, bbbCredential.sharedSecret) to use
buildSignedUrl/buildChecksum to produce a signed URL.

In `@packages/app-store/bigbluebuttonvideo/zod.ts`:
- Line 10: Update the zod string validator for sharedSecret to trim whitespace
before checking non-emptiness: replace the current z.string().min(1) for the
sharedSecret field with a transformed/trimmed string validator (e.g.,
z.string().transform(s => s.trim()).min(1)) so whitespace-only values are
rejected; modify the sharedSecret schema entry accordingly.

---

Nitpick comments:
In `@apps/web/components/apps/appsWithSetupForm.ts`:
- Around line 1-5: The top-of-file comment blocks are "what" comments that
restate behavior; remove or rewrite them to capture the rationale for the
special-case list of app slugs (i.e., why certain non-OAuth apps require a
custom setup form and must follow the setup flow instead of the auto-install
flow). Update the comment(s) near the list(s) in appsWithSetupForm.ts (and the
similar blocks referenced around the other comment ranges) to be terse and
intent-focused: explain the non-obvious design decision or constraint (e.g.,
credential storage semantics, security or UX reasons, or upstream API
differences) that necessitates using a setup form, rather than describing the
behavior itself. Ensure the new comment references the list's purpose only in
terms of the why, then remove any redundant explanatory lines.

In `@apps/web/components/apps/bigbluebuttonvideo/Setup.tsx`:
- Line 20: Remove the comment(s) that state obvious facts (e.g. the /* 表单字段验证模式
*/ and the similar comments at lines 28-31) from the Setup component; if
additional context is needed, replace them with a brief "why" comment explaining
intent or rationale for the validation mode/behavior used in the Setup.tsx
component (reference the Setup component and any local validation-related
variables/props to place the why-comment).

In `@apps/web/lib/apps/installation/`[[...step]]/getServerSideProps.ts:
- Line 451: The inline comment "// 无凭证且 app 需要 setup form 时,重定向到 setup 页面采集凭证"
in getServerSideProps is restating the code path; remove it or replace it with a
brief rationale explaining the non-obvious intent (e.g., why redirecting here is
required for UX/consistency or to avoid exposing partial app state). Locate the
comment near the getServerSideProps handler in
apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts and either
delete that line or swap it for a one-sentence "why" comment referencing the
redirect's purpose and any trade-offs (security/UX), not the "what".

In `@apps/web/modules/apps/components/AppCard.tsx`:
- Line 75: Remove the redundant inline “what” comment above the setup-form
branch in the AppCard component: open the AppCard component (symbol AppCard) and
delete the single-line Chinese comment that restates behavior for setup-form
apps so only necessary rationale comments remain, keeping the control flow
self-explanatory.

In `@packages/app-store/bigbluebuttonvideo/api/add.ts`:
- Around line 13-18: The comments in the BigBlueButton installation handler
(packages/app-store/bigbluebuttonvideo/api/add.ts — the POST handler function)
are “what” comments that merely restate code flow; remove or replace them so
only non-obvious rationale remains (explain why decisions were made, e.g., why
you validate with getMeetings, why you encrypt the secret, any security
assumptions or edge cases), and delete redundant inline comments around the
credential validation, encryption/storage, and redirect logic (currently near
the credential parsing, getMeetings call, encryption step, and redirect
response). Ensure any retained comments explain intent or trade-offs rather than
restating actions.

In `@packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.ts`:
- Around line 17-24: Replace the plain Error throws in VideoApiAdapter.ts with
the project's ErrorWithCode so credential/config validation failures follow the
repo's non-tRPC error contract: where encryptionKey is validated (the branch
throwing "CALENDSO_ENCRYPTION_KEY environment variable is not set.") and where
credentialKey type is checked (the branch throwing "Invalid credential key
format."), throw new ErrorWithCode with an appropriate code (e.g., "BAD_REQUEST"
or "INVALID_CREDENTIALS") and descriptive message; also add the ErrorWithCode
import at the top of the file if not present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4495d7a2-4380-42e1-b485-23391125aeaa

📥 Commits

Reviewing files that changed from the base of the PR and between 180ede2 and 9e9afec.

⛔ Files ignored due to path filters (1)
  • packages/app-store/bigbluebuttonvideo/static/icon.svg is excluded by !**/*.svg
📒 Files selected for processing (24)
  • apps/web/components/apps/AppSetupPage.tsx
  • apps/web/components/apps/appsWithSetupForm.ts
  • apps/web/components/apps/bigbluebuttonvideo/Setup.tsx
  • apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
  • apps/web/modules/apps/components/AppCard.tsx
  • packages/app-store/apps.keys-schemas.generated.ts
  • packages/app-store/apps.metadata.generated.ts
  • packages/app-store/apps.schemas.generated.ts
  • packages/app-store/apps.server.generated.ts
  • packages/app-store/bigbluebuttonvideo/DESCRIPTION.md
  • packages/app-store/bigbluebuttonvideo/_metadata.ts
  • packages/app-store/bigbluebuttonvideo/api/add.ts
  • packages/app-store/bigbluebuttonvideo/api/index.ts
  • packages/app-store/bigbluebuttonvideo/index.ts
  • packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.test.ts
  • packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.ts
  • packages/app-store/bigbluebuttonvideo/lib/bbbClient.test.ts
  • packages/app-store/bigbluebuttonvideo/lib/bbbClient.ts
  • packages/app-store/bigbluebuttonvideo/lib/index.ts
  • packages/app-store/bigbluebuttonvideo/package.json
  • packages/app-store/bigbluebuttonvideo/zod.ts
  • packages/app-store/bookerApps.metadata.generated.ts
  • packages/app-store/video.adapters.generated.ts
  • packages/i18n/locales/en/common.json

Comment thread apps/web/components/apps/bigbluebuttonvideo/Setup.tsx
Comment thread apps/web/components/apps/bigbluebuttonvideo/Setup.tsx Outdated
Comment on lines +452 to +455
if (!credentialId && !appMetadata.isOAuth) {
const setupRedirect = setupFormRedirectFor(parsedAppSlug);
if (setupRedirect) return setupRedirect;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify return statements inside getCredential and compare shape expectations.
rg -n "const getCredential|return \\{ credentialId|return setupRedirect|Promise<\\{ credentialId" apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts

Repository: calcom/cal.diy

Length of output: 391


Fix getCredential return shape when redirecting to the setup form.

getCredential is typed to return Promise<{ credentialId: number | null; redirect?: RedirectResult }>, but the setupRedirect branch returns setupRedirect directly (missing credentialId, around lines 452–455), causing a TypeScript contract mismatch.

Suggested fix
   if (!credentialId && !appMetadata.isOAuth) {
     const setupRedirect = setupFormRedirectFor(parsedAppSlug);
-    if (setupRedirect) return setupRedirect;
+    if (setupRedirect) return { credentialId: null, redirect: setupRedirect };
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!credentialId && !appMetadata.isOAuth) {
const setupRedirect = setupFormRedirectFor(parsedAppSlug);
if (setupRedirect) return setupRedirect;
}
if (!credentialId && !appMetadata.isOAuth) {
const setupRedirect = setupFormRedirectFor(parsedAppSlug);
if (setupRedirect) return { credentialId: null, redirect: setupRedirect };
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/lib/apps/installation/`[[...step]]/getServerSideProps.ts around
lines 452 - 455, The getCredential branch that checks if (!credentialId &&
!appMetadata.isOAuth) calls setupFormRedirectFor(parsedAppSlug) and returns
setupRedirect directly, which violates the declared return type Promise<{
credentialId: number | null; redirect?: RedirectResult }>; instead, change that
branch to return an object with credentialId: null and redirect: setupRedirect
(i.e., return { credentialId: null, redirect: setupRedirect }) so the function
signature is honored while preserving the redirect behavior.

Comment on lines +71 to +76
const alreadyInstalled = await prisma.credential.findFirst({
where: {
type: appType,
...installForObject,
},
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify credential queries in this handler and whether they use select/include.
rg -n -C3 'prisma\.credential\.(findFirst|create)\(' packages/app-store/bigbluebuttonvideo/api/add.ts

Repository: calcom/cal.diy

Length of output: 438


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/app-store/bigbluebuttonvideo/api/add.ts"

echo "== findFirst block =="
nl -ba "$FILE" | sed -n '60,95p'

echo
echo "== create block =="
nl -ba "$FILE" | sed -n '90,140p'

echo
echo "== Any reference to installation/alreadyInstalled fields =="
rg -n "alreadyInstalled|installation" "$FILE" -n

Repository: calcom/cal.diy

Length of output: 141


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/app-store/bigbluebuttonvideo/api/add.ts"

echo "== findFirst block (lines ~60-95) ==" 
cat -n "$FILE" | sed -n '60,95p'

echo
echo "== create block (lines ~88-140) ==" 
cat -n "$FILE" | sed -n '88,140p'

echo
echo "== Check select/include on prisma.credential.* in this file ==" 
rg -n --context 2 "prisma\.credential\.(findFirst|create)\(" "$FILE"
rg -n --context 2 "select\s*:\s*\{|include\s*:\s*\{" "$FILE"

echo
echo "== References to installation/alreadyInstalled in this file ==" 
rg -n "alreadyInstalled|installation" "$FILE"

Repository: calcom/cal.diy

Length of output: 2671


Restrict Prisma credential queries to non-sensitive fields

  • prisma.credential.findFirst returns the full credential row without select; this should be limited to non-sensitive fields (e.g., id) since it’s only used as a boolean check.
  • prisma.credential.create also returns the full row without select; limit the returned fields (e.g., id) so credential.key isn’t materialized unnecessarily.
Proposed fix
-    const alreadyInstalled = await prisma.credential.findFirst({
+    const alreadyInstalled = await prisma.credential.findFirst({
       where: {
         type: appType,
         ...installForObject,
       },
+      select: { id: true },
     });
@@
-    const installation = await prisma.credential.create({
+    await prisma.credential.create({
       data: {
         type: appType,
         key: encryptedKey as unknown as Prisma.JsonValue,
         ...installForObject,
         appId: "bigbluebutton",
       },
+      select: { id: true },
     });
-
-    if (!installation) {
-      throw new Error("Unable to create user credential for bigbluebuttonvideo");
-    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app-store/bigbluebuttonvideo/api/add.ts` around lines 71 - 76, The
Prisma queries currently materialize full credential rows; change
prisma.credential.findFirst (used to set alreadyInstalled) to select only
non-sensitive fields (e.g., select: { id: true }) so you only check existence,
and likewise change prisma.credential.create to return only non-sensitive fields
(e.g., select: { id: true }) so credential.key is not materialized
unnecessarily; update the calls referencing prisma.credential.findFirst and
prisma.credential.create accordingly.

Comment thread packages/app-store/bigbluebuttonvideo/api/add.ts
Comment thread packages/app-store/bigbluebuttonvideo/lib/bbbClient.test.ts
Comment thread packages/app-store/bigbluebuttonvideo/lib/bbbClient.ts Outdated
Comment thread packages/app-store/bigbluebuttonvideo/lib/bbbClient.ts
Comment on lines +86 to +95
// 构建参会者加入链接:attendeePW 直接嵌入 URL
const joinUrl = buildUrl({
baseUrl: bbbCredential.serverUrl,
path: `/api/join`,
queryParams: {
meetingID: meetingId,
password: attendeePW,
fullName: "Guest",
},
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.ts"

echo "== File context =="
wc -l "$FILE"
echo

echo "== Snippet around lines 70-120 =="
sed -n '70,120p' "$FILE" | cat -n

echo
echo "== Snippet around lines 130-200 =="
sed -n '130,200p' "$FILE" | cat -n

echo
echo "== Search for checksum/signing/join URL helpers in this file =="
rg -n "checksum|sign|signature|join.*checksum|api/join|buildUrl\\(" "$FILE" || true

echo
echo "== Search repo for any helper that generates BBB join/checksum URLs =="
rg -n "joinUrl|api/join|checksum" packages/app-store/bigbluebuttonvideo/lib || true

echo
echo "== Search repo for BigBlueButton signing implementation (Key/secret, query signing, HMAC, etc.) =="
rg -n "CALENDSO_ENCRYPTION_KEY|decryptCredentialKey|hmac|HMAC|crypto|md5\\(|sha1\\(|signature|checksum" packages/app-store/bigbluebuttonvideo/lib || true

Repository: calcom/cal.diy

Length of output: 10881


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE1="packages/app-store/bigbluebuttonvideo/lib/bbbClient.ts"
FILE2="packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.ts"

echo "== bbbClient.ts (top) =="
sed -n '1,140p' "$FILE1" | cat -n

echo
echo "== VideoApiAdapter.ts (decryptCredentialKey) =="
sed -n '1,120p' "$FILE2" | cat -n

echo
echo "== VideoApiAdapter.ts (createMeeting joinUrl return) =="
sed -n '60,120p' "$FILE2" | cat -n

echo
echo "== VideoApiAdapter.ts (updateMeeting joinUrl return) =="
sed -n '120,190p' "$FILE2" | cat -n

echo
echo "== Search within VideoApiAdapter.ts for ErrorWithCode usage =="
rg -n "ErrorWithCode" "$FILE2" || true

Repository: calcom/cal.diy

Length of output: 13226


Sign the BBB /api/join URLs (missing checksum)

createMeeting and updateMeeting return join URLs built via buildUrl(...path: \/api/join`...)withmeetingID, password, and fullName, but **no checksum`**—so participant join links can fail.

// 构建参会者加入链接:attendeePW 直接嵌入 URL
const joinUrl = buildUrl({
  baseUrl: bbbCredential.serverUrl,
  path: `/api/join`,
  queryParams: {
    meetingID: meetingId,
    password: attendeePW,
    fullName: "Guest",
  },
});

Generate these join URLs using the existing BBB signing flow (e.g., buildSignedUrl/buildChecksum) with bbbCredential.sharedSecret and the exact queryString used in the URL. (Applies to both the createMeeting join URL and the updateMeeting join URL.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app-store/bigbluebuttonvideo/lib/VideoApiAdapter.ts` around lines 86
- 95, The join URL for attendees is missing the required BigBlueButton
checksum—replace the direct buildUrl(...) usage in the createMeeting and
updateMeeting flows with the existing BBB signing utilities: construct the same
query string used for buildUrl (meetingID, password/attendeePW, fullName) and
pass it to buildChecksum or buildSignedUrl together with
bbbCredential.sharedSecret so the generated joinUrl includes the checksum;
update the call sites that currently call buildUrl(...) (referencing buildUrl,
meetingId, attendeePW, bbbCredential.sharedSecret) to use
buildSignedUrl/buildChecksum to produce a signed URL.

Comment thread packages/app-store/bigbluebuttonvideo/zod.ts Outdated
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

- Add zodResolver to Setup form for proper validation
- Trim sharedSecret in zod schema to prevent whitespace-only values
- Fix XMLValidator return type check (true vs object with err)
- Add network/abort error handling in callBbb with BbbApiError
- Replace generic Error with ErrorWithCode in add.ts
- Fix contradictory checksum assertion in bbbClient.test.ts
- Move server URL placeholder to i18n keys
Copy link
Copy Markdown
Member

@bandhan-majumder bandhan-majumder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a working demo in the description!

@bandhan-majumder bandhan-majumder marked this pull request as draft June 4, 2026 19:16
@bandhan-majumder
Copy link
Copy Markdown
Member

Thank u for ur contribution. Closing. please refer: #1985 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app-store area: app store, apps, calendar integrations, google calendar, outlook, lark, apple calendar 💎 Bounty A bounty on Algora.io community Created by Linear-GitHub Sync consumer ✨ feature New feature or request 🙋🏻‍♂️help wanted Help from the community is appreciated size/XXL $50

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CAL-3105] BigBlueButton Integration

3 participants