Compare commits

..

234 Commits

Author SHA1 Message Date
juancarmore
029802787a Reapply "Revert commits 6c7bfd4 5638025 da7759d ba374ce cf84de4 39a9b7d e990c19"
This reverts commit 450aa85b887e2ce56052c8abe75fbe4722a2ef69.
2026-03-06 17:00:20 +01:00
GitHub Actions
ad413d2791 Bump version to 3.6.0 2026-03-06 11:37:26 +00:00
CSantosM
d025a35e15 frontend: update participant role notification handling in MeetingEventHandlerService 2026-03-04 16:05:13 +01:00
CSantosM
1761517afc backend: update '@livekit/track-processors' to version 0.7.2 2026-03-04 13:59:18 +01:00
juancarmore
9278260837 frontend: improve recording action buttons with consistent attributes and structure 2026-03-04 13:52:35 +01:00
CSantosM
53f62708ce backend(test): increase sleep duration for webhook processing in expired rooms GC test 2026-03-04 12:56:42 +01:00
CSantosM
ba0d0b10c4 backend: Enhances LiveKit agent robustness
LiveKit agent service calls now gracefully handle errors instead of throwing exceptions.

`listAgents` and `getAgent` return sensible defaults (empty array, undefined) on failure, preventing disruption to calling services. `stopAgent` now logs errors during deletion without halting the process.

An early exit condition is also added in the AI assistant service to prevent unnecessary processing if no agents are found, further improving resilience.
2026-03-04 12:33:36 +01:00
CSantosM
8953e9891c backend(test): Extends test sleep for webhook processing
Increases the sleep duration in room deletion test helpers from 1 second to 5 seconds. This ensures that webhooks triggered by room deletion have enough time to process before test execution continues, addressing intermittent test failures caused by premature assertions. This is a temporary measure to improve test stability.
2026-03-04 12:28:35 +01:00
CSantosM
02703b1f83 frontend: enhance captions button functionality and integrate AI assistant for live captions 2026-03-03 19:13:42 +01:00
CSantosM
c808e98820 backend(ai-assistant): implement AI assistant creation and management
- Add OpenAPI components for creating and responding to AI assistant requests.
- Implement AI assistant service for managing live captions capability.
- Create routes and controllers for AI assistant operations (create and cancel).
- Introduce request validation middleware for AI assistant requests.
- Update Redis helper to manage AI assistant locks.
- Integrate AI assistant cleanup in webhook service.
- Enhance LiveKit service to manage agent dispatch for AI assistants.
- Update token service to remove unnecessary parameters related to captions.
- Add typings for AI assistant requests and responses.
2026-03-03 18:43:35 +01:00
CSantosM
56d5126acb frontend: update @livekit/track-processors dependency to version 0.7.2 2026-03-02 17:15:29 +01:00
juancarmore
ac3a728591 Revert "frontend: Refactor user management components and update routes"
This reverts commit f677b18879bb13acf063de6a3366059a3a49d3ed.
2026-02-17 17:40:50 +01:00
juancarmore
90a1c6fde9 backend: refactor migration transforms to return updated document instances and improve MigrationService to execute all transforms sequantilly for each document 2026-02-17 16:03:05 +01:00
juancarmore
7378a8f53e backend: create schema migrations for room and recording from v1 to v2 version 2026-02-17 12:47:31 +01:00
juancarmore
3142f9fe79 backend: update migration README to clarify schema versioning and MIGRATION_REV timestamp requirements 2026-02-17 12:46:38 +01:00
juancarmore
2a1575768f backend: use collection names in schema migration name generation 2026-02-17 12:32:01 +01:00
juancarmore
396c23aa3c backend: remove unused repository injections from MigrationService 2026-02-17 12:30:26 +01:00
juancarmore
96e441726c refactor(migrations): overhaul migration system to use schema transformation maps
- Removed the BaseSchemaMigration class and replaced it with a more flexible schema migration approach using transformation functions.
- Updated global-config, recording, room, and user migrations to utilize the new schema migration map structure.
- Introduced runtime migration registry for better management of migration execution.
- Enhanced migration service to handle schema migrations more efficiently, including improved error handling and logging.
- Added utility functions for generating and validating schema migration names.
- Updated migration repository methods to streamline migration status tracking.
2026-02-17 11:32:34 +01:00
cruizba
a853aa02a2 backend: apply dynamic base path to OpenAPI docs server URLs
When deployed under a base path (e.g. /meet), the Stoplight "Try It"
requests were hitting /api/v1 instead of /meet/api/v1. This applies
the base path to the embedded OpenAPI spec's servers array at serve time,
following the same pattern used for the frontend index.html.

Also renames html-injection.utils to html-dynamic-base-path.utils and
updates function names for better wording.
2026-02-11 19:18:30 +01:00
cruizba
366632741c fix: strip basePath prefix in redirectTo method
Strip basePath prefix if present, since Angular router operates relative to <base href>
2026-02-05 19:40:00 +01:00
CSantosM
1046b5a0dd backend: enhance build script to generate API documentation after compilation 2026-02-05 12:40:49 +01:00
CSantosM
59d722f882 backend: enhance recording start process sending FAILED event to client when an error occurs 2026-02-04 15:21:25 +01:00
cruizba
b08bb10f63 backend: fix URL path extraction to remove basePath prefix 2026-02-03 01:56:58 +01:00
cruizba
177648e6d5 tests: Use getFullPath for constructing recording URLs in assertions 2026-02-02 21:09:34 +01:00
cruizba
b059b88be4 fix tests: Update API path construction with new path 2026-02-02 20:51:03 +01:00
cruizba
4e634dac54 Move LiveKit Webhook route to app level 2026-02-02 19:58:38 +01:00
cruizba
b0c7dcbc9a Introduce base path configuration and update related services 2026-02-02 19:47:18 +01:00
CSantosM
ba7600bfc5 test: Fix default captions config enabled state to false 2026-02-02 17:01:41 +01:00
CSantosM
accb35c7e1 Adds recording encoding options to room config and start recording
Adds configuration options for recording encoding, including presets and advanced settings, allowing users to customize video and audio quality.

This enhancement introduces new schemas for recording encoding presets and advanced options, enabling users to select from predefined encoding profiles or fine-tune specific video and audio parameters.

A conversion helper is implemented to translate between the internal encoding configurations and the format required by the LiveKit SDK.

backend: Adds recording encoding configuration options

Allows users to specify custom audio and video encoding settings for recordings, overriding room defaults.

This enhancement provides greater flexibility in controlling recording quality and file size. It introduces new schema definitions for encoding options and validates these configurations through Zod schemas.

Enforces complete video/audio encoding options

Requires both video and audio configurations with all their properties
when using advanced encoding options for recordings. This change ensures
complete encoding setups and prevents potential recording failures due to
missing encoding parameters. It also corrects a typo of keyframeInterval.

Add video depth option to recording encoding settings
2026-02-02 17:00:01 +01:00
CSantosM
1add921ce0 backend: Allows overriding recording layout
Enables users to override the default recording layout for a room
when starting a recording. This allows customization of the recording
appearance on a per-recording basis, instead of being tied solely to the
room's configuration.
2026-01-28 18:14:29 +01:00
CSantosM
2fe720c90b test: Remove moderatorToken from start and stop recording tests 2026-01-28 18:07:00 +01:00
CSantosM
3f91e281b3 frontend: Controls captions button based on admin config
Updates the captions button to respect the global admin configuration.

The button now displays a disabled state and tooltip when captions are disabled globally, preventing users from toggling them.

The UI is updated to show disabled state and a specific subtitle off icon,
reflecting whether captions are enabled at the system level.
2026-01-28 16:27:30 +01:00
CSantosM
4ac182c244 backend: Update captions agent name and improve environment checks in TokenService 2026-01-28 16:25:43 +01:00
CSantosM
43f7ff5001 backend: Exposes captions config via internal API
Adds an internal API endpoint to retrieve the captions configuration,
allowing the frontend to determine whether captions are enabled.
The configuration is read from the MEET_CAPTIONS_ENABLED environment variable.
2026-01-28 15:21:00 +01:00
CSantosM
30bd4b5a41 Enable captions by default in room configurations and related tests 2026-01-28 14:50:32 +01:00
CSantosM
00433c75a4 Updated pnpm-lock.yaml 2026-01-26 17:21:30 +01:00
CSantosM
becf3070b0 test: Enhance E2EE UI tests by improving chat panel visibility checks and adding wait for animations 2026-01-26 16:46:16 +01:00
CSantosM
21e939e09c Update Jest configuration for integration tests and improve command line options 2026-01-26 14:10:53 +01:00
CSantosM
659cdcaf73 webcomponent: Updates dependencies and improves end-to-end tests
Upgrades Playwright dependency to the latest version.

Removes unnecessary test cleanup functions and simplifies test structure.
Improves test stability by properly handling browser resources.
2026-01-26 13:59:40 +01:00
CSantosM
dbcc9bbb25 test: Improve room closure check with retry logic in delete room tests 2026-01-26 11:09:00 +01:00
CSantosM
215b11e93f Moves recording API to public endpoint
This commit refactors the recording API endpoints from the internal API to the public API.

This change allows users to start and stop recordings using API keys, enabling more secure and flexible access control for recording functionality. It also centralizes recording-related logic in the public API, simplifying the codebase and improving maintainability.
2026-01-23 17:32:18 +01:00
CSantosM
55aab084b0 backend: Add captions configuration to room tests 2026-01-23 16:38:50 +01:00
CSantosM
96b5cd249e testapp: Add captions configuration to room settings and UI 2026-01-23 14:28:30 +01:00
CSantosM
4751e7e989 dockerignore: Remove audio file extensions from ignore list 2026-01-23 10:23:49 +01:00
CSantosM
0a56a74433 frontend: Enables user-controlled live captions
Allows users to toggle live captions on or off.
Introduces a room configuration setting to enable/disable the captions feature.
The captions button visibility is now controlled by the 'showCaptions' feature flag.
2026-01-22 19:28:18 +01:00
CSantosM
cb12d9a8fe backend: Add captions configuration test 2026-01-22 18:35:35 +01:00
CSantosM
9ae27bf32a backend: Adds live captions functionality to rooms
Adds support for live captions in meet rooms.
This includes schema definitions, API configurations,
and LiveKit integration for dispatching captions agents.
Captions are disabled by default and can be enabled per room.
2026-01-22 18:24:50 +01:00
CSantosM
f677b18879 frontend: Refactor user management components and update routes 2026-01-21 18:22:09 +01:00
CSantosM
f95b02e42b frontend: Comment out handleRoomConfigUpdated method for future reference 2026-01-21 17:31:51 +01:00
CSantosM
5f8af67ac6 frontend: Enhances user experience on role updates
Adds a notification and sound effect to inform users when their role is updated.

This provides immediate feedback to the user and improves the overall user experience.
2026-01-21 17:31:34 +01:00
CSantosM
1ef813e509 frontend: Moves sound effects to dedicated service
Refactors sound effect logic into a dedicated `SoundService`.

This change centralizes audio playback functionality, promoting
better code organization and reusability. Removes sound effect logic
from the meeting service.
2026-01-21 17:30:30 +01:00
CSantosM
011e44b4f9 frontend: Removed allowSignalWrites flag because of it is deprecated 2026-01-21 17:28:52 +01:00
CSantosM
ed057612a0 frontend: Update moderation tooltips and move display properties interface 2026-01-21 17:01:23 +01:00
CSantosM
5cdc49d90c frontend: Adds live captions component
Introduces a live captions feature using LiveKit's transcription service.

This adds a new component that displays real-time transcriptions of the meeting audio in. It manages caption lifecycles, handles both interim and final transcriptions, and
provides reactive signals for UI updates.
2026-01-21 12:47:09 +01:00
CSantosM
073f0dc640 backend: Adds speech processing agent support
Enables the capability to integrate speech processing agents by adding room configuration to the token when the agent processing name is set in the environment.
This allows to specify the agent to be dispatched on room creation.
2026-01-21 12:37:06 +01:00
CSantosM
bbd4d5fbaf frontend: Remove unused DestroyRef injection in MeetingContextService 2026-01-21 09:02:20 +01:00
CSantosM
5f722c36e7 frontend: Add sound notification for participant joining the meeting 2026-01-19 17:08:21 +01:00
CSantosM
b5ccd7c087 frontend: Enhance meeting component to manage participant left events and update state 2026-01-18 16:38:55 +01:00
Carlos Santos
13a339eb87 backend: Add main entry point and organize module exports 2026-01-15 16:57:18 +01:00
Carlos Santos
1d5cd9be26 backend: Fix import order and improve path resolution logic 2026-01-15 16:57:01 +01:00
Carlos Santos
68a10ff901 frontend: Refactors selection logic in lists
Ensures the selected items in lists are correctly updated
when the underlying data changes by using `untracked` to avoid circular dependencies.

Introduces a utility function to compare sets for equality,
preventing unnecessary updates and improving performance.
2026-01-15 16:56:19 +01:00
Carlos Santos
eabb559a82 frontend: Reset nextPageToken before refreshing recordings and rooms 2026-01-15 15:36:58 +01:00
Carlos Santos
e70dc6619f frontend: Refactors rooms lists component to use Angular signals
Migrates the rooms lists component to leverage Angular's signal-based inputs.
This improves change detection and simplifies data flow within the component.

Updates the component's template to reflect the use of signal accessors.
Ensures initial filters are correctly applied.
2026-01-15 14:55:43 +01:00
Carlos Santos
520816b983 frontend: Refactors recording list component to use signals
Migrates the recording list component to use Angular signals for input properties and data binding.
This improves performance and simplifies the component's change detection.

- Converts input properties to input signals.
- Uses computed signals for derived values.
- Introduces effect for side effects related to recordings changes.
- Moves recording list model interfaces to shared location.
2026-01-15 14:43:19 +01:00
Carlos Santos
b24992ad24 frontend: Improves HTTP error handling
Refactors error handling to allow handlers to directly return a response.

Updates the error handler service to return null when no handler can process an error.
2026-01-15 13:11:18 +01:00
Carlos Santos
d9e064e971 frontend: Rename initializeTheme method to init for consistency 2026-01-15 12:12:15 +01:00
Carlos Santos
8af00ab6ee frontend: Refactor app component and meeting component to use inline templates and remove unused files 2026-01-15 12:06:49 +01:00
Carlos Santos
2ec42f701d frontend: Enhance E2EE UI tests by adding visibility checks for panel close button and more options menu 2026-01-15 10:59:16 +01:00
Carlos Santos
f77630d1e0 Revert "frontend: Improve E2EE UI tests by enhancing panel close interactions and timeout handling"
This reverts commit 3cb163deee6c306b52ce0bb6d96d4151a1aa8e6e.
2026-01-15 10:26:39 +01:00
Carlos Santos
3cb163deee frontend: Improve E2EE UI tests by enhancing panel close interactions and timeout handling 2026-01-14 19:37:53 +01:00
Carlos Santos
4ecd086f21 backend: Adds layout property to recording info
Adds the 'layout' property to recording information.

This allows tracking the layout used during a recording, enhancing recording metadata.

Updates recording schema and adds layout information to API responses.
2026-01-14 18:46:38 +01:00
Carlos Santos
a1acc9ba22 frontend: Refactor webhook event storage to use sessionStorage and enhance webhook handling in E2E tests 2026-01-14 18:27:33 +01:00
Carlos Santos
0368ab83e6 frontend: Enhance unit tests for WebComponent attributes, commands, events, and lifecycle handling 2026-01-14 17:22:02 +01:00
Carlos Santos
082aa8480c frontend: Configures the application routing
Sets up domain-based routing for different app features.

This change introduces a structured approach to managing application routes,
making it easier to add, modify, and maintain different sections of the application.
It configures routes for authentication, meetings, rooms, recordings, and the console.
2026-01-14 13:57:03 +01:00
Carlos Santos
ca2d41b05e frontend: Remove unused service dependencies from RecordingService 2026-01-14 12:57:26 +01:00
Carlos Santos
db62cf0e1c frontend: Provides adapter interfaces for shared guards
Creates adapter interfaces for meeting context and room member operations.

This allows shared guards to interact with meeting context and room member context without directly depending on domain services, improving modularity and testability.

Adds providers to supply the adapters using existing services, enabling the use of the adapter interface within the guards.
2026-01-14 11:37:33 +01:00
Carlos Santos
3eb06e41e2 frontend: Add confirm dialog component with customizable actions and styles 2026-01-13 18:28:04 +01:00
Carlos Santos
56e025d23d frontend: Moves delete room dialog to rooms domain
Relocates the delete room dialog component to the rooms domain for better organization and separation of concerns.

Updates imports and references to reflect the new location of the component.
2026-01-13 18:21:07 +01:00
Carlos Santos
6c730a6dbc frontend: Remove unused README files for Auth and Rooms interceptor handlers 2026-01-13 17:37:11 +01:00
Carlos Santos
163e0d5f99 frontend: Update meeting route to use dynamic component loading for AppCeMeetingComponent 2026-01-13 17:36:57 +01:00
Carlos Santos
834dc2be42 frontend: Update E2EE UI tests to reflect changes in expected video poster counts 2026-01-13 17:36:31 +01:00
Carlos Santos
7cddb59e2d frontend: Refactors recording URL generation
Moves recording URL generation to the component using the URL.

This provides more flexibility in how the URL is generated,
allowing the component to handle different scenarios.
The service is no longer responsible for generating the URL.
2026-01-12 20:13:26 +01:00
Carlos Santos
8afed3a2f8 frontend: Refactors project structure for better organization
Moves code into domain-specific folders for better modularity.
Updates imports to reflect the new directory structure.
2026-01-12 19:51:49 +01:00
Carlos Santos
dac64bb1a9 frontend: project restructuring by domain
- centralize HTTP interceptor error handling via registry and handlers
2026-01-12 17:52:46 +01:00
Carlos Santos
c42a3ce1cf frontend: refactor layout option IDs to use constants from MeetRecordingLayout 2026-01-09 11:57:41 +01:00
Carlos Santos
6455a4937c frontend: refactor GlobalConfigService to use Angular's inject for dependency injection 2026-01-09 11:51:23 +01:00
Carlos Santos
4bee373e85 frontend: refactor ConfigComponent to use Angular's inject for services 2026-01-09 11:50:01 +01:00
Carlos Santos
e0c0453a02 frontend: refactor ColorField and ThemeColors types for color configuration 2026-01-09 11:48:30 +01:00
Carlos Santos
7a83cc57fd frontend: remove unused imports in MeetingComponent 2026-01-09 11:38:03 +01:00
Carlos Santos
7d6f61e12c frontend: update default layout mode to SMART_MOSAIC in MeetLayoutService 2026-01-09 11:37:51 +01:00
Carlos Santos
6f841eb254 Adds recording layout configuration
Enables configuration of recording layouts.

Specifies the recording layout in the room configuration.
Now supports different layouts, such as grid, speaker, and single-speaker.
Updated zod validation schemas
Updated integration tests
2026-01-08 19:51:04 +01:00
Carlos Santos
be5e3ffb1d backend: enhance room configuration schemas for updates and creation 2026-01-07 19:51:35 +01:00
Carlos Santos
0ba9d0b297 backend: Simplifies room configuration
The default configuration is assigned in the API validator middleware.
Streamlines the room configuration process by directly using the provided configuration options.
2026-01-07 18:01:14 +01:00
juancarmore
caad4bc550 backend: remove legacy storage service and migration process 2026-01-07 14:07:40 +01:00
juancarmore
450aa85b88 Revert "Revert commits 6c7bfd4 5638025 da7759d ba374ce cf84de4 39a9b7d e990c19"
This reverts commit 0ab6a48e13ec15267de4373f2647745cc184bb87.
2026-01-07 10:13:08 +01:00
juancarmore
86af733b37 backend: fix filename format for API keys in S3KeyBuilder 2025-12-31 00:51:56 +01:00
juancarmore
8d685e6ae5 test: enhance recordings and rooms API tests with filtering and sorting functionality 2025-12-31 00:14:14 +01:00
juancarmore
05980df465 test: update import paths for RoomData and TestContext in various test files 2025-12-31 00:12:48 +01:00
juancarmore
744fd05724 frontend: improve promise handling in MeetingLobbyService 2025-12-29 17:42:06 +01:00
cruizba
d1431687f0 bump to 3.5.0 2025-12-29 13:11:46 +01:00
juancarmore
87b86652dc backend: update room creation to use roomConfig correctly 2025-12-25 14:18:02 +01:00
Carlos Santos
115993fe69 frontend: adjust horizontal layout styles for improved spacing and responsiveness 2025-12-23 16:50:49 +01:00
Carlos Santos
f65f5dd33d frontend: refactor hidden participants indicator styles for improved layout and consistency 2025-12-23 13:51:16 +01:00
Carlos Santos
d78eae9810 frontend: update styles in hidden participants indicator for improved consistency and theming 2025-12-23 13:35:07 +01:00
Carlos Santos
8fbe8fb716 frontend: enhance hidden participants indicator to display names of hidden participants in both horizontal and vertical layouts 2025-12-23 13:08:25 +01:00
Carlos Santos
6a9bd2be95 frontend: adjust step content card styles for improved layout and add height property to recordings header for better UX 2025-12-23 11:40:27 +01:00
Carlos Santos
320135dd39 frontend: fix overflow property in users permissions icon for better styling 2025-12-23 11:35:30 +01:00
Carlos Santos
0ca445a89b frontend: refine layout and spacing in room details component for improved visual consistency 2025-12-23 11:25:54 +01:00
Carlos Santos
76ea36cf69 frontend: refactor filter menu styles for consistency across recording and rooms lists components 2025-12-23 11:02:58 +01:00
juancarmore
b0b95f38a8 frontend: remove UtilsHelper and update repositories and services to handle field selection directly in database 2025-12-23 01:05:01 +01:00
juancarmore
6ad700f538 frontend: enhance empty state message in recording lists to show room-specific information 2025-12-22 21:50:19 +01:00
juancarmore
11dcd1238a frontend: update room recordings component to support filters and sorting 2025-12-22 21:22:56 +01:00
juancarmore
8f858267b4 frontend: implement sorting functionality in rooms list and update filters to support sorting options 2025-12-22 20:53:26 +01:00
juancarmore
cea8301e00 frontend: add sorting functionality to recording lists and update filters to include sort options 2025-12-22 20:31:41 +01:00
juancarmore
f2c4df0de6 frontend: enable filters in rooms list and update room service to support status and sorting options 2025-12-22 19:29:12 +01:00
juancarmore
eb3e11c37c frontend: enable filters in recording lists and update filter handling in service 2025-12-22 17:35:54 +01:00
juancarmore
f5b805f3a3 backend: enhance recording and room repositories with additional filtering options 2025-12-22 17:21:57 +01:00
juancarmore
1c955c60d0 backend: enhance recording and room filters with status and sorting options 2025-12-22 17:21:57 +01:00
juancarmore
113dbe4f88 openapi: add query parameters for status, sort field, and sort order in get all endpoints 2025-12-22 17:21:57 +01:00
juancarmore
f6d685a158 backend: modify room config validator and ensure recording is disabled when E2EE is enabled 2025-12-22 17:21:57 +01:00
Carlos Santos
60cb1afdf3 frontend: implement automatic participant synchronization using signals in MeetingContextService 2025-12-22 16:54:51 +01:00
Carlos Santos
b4f482f9d7 frontend: enhance hidden participants indicator with improved layout and description text 2025-12-22 16:54:36 +01:00
Carlos Santos
3a83efa668 frontend: add hidden participants indicator component with responsive layouts 2025-12-22 14:12:17 +01:00
juancarmore
0ab6a48e13 Revert commits 6c7bfd4 5638025 da7759d ba374ce cf84de4 39a9b7d e990c19 2025-12-19 12:48:22 +01:00
Carlos Santos
9a853f285b test: remove console logs and update chat message expectations in E2EE UI tests 2025-12-17 17:47:28 +01:00
Carlos Santos
1d552c9098 frontend: refactor isMobileView to use computed property for better performance 2025-12-17 11:44:49 +01:00
Carlos Santos
c806e90e42 docker: update Node.js version in Dockerfile to 22.21.1 2025-12-17 11:20:08 +01:00
Carlos Santos
3a2ce89a3d chore: update dependencies to latest versions
- Updated dotenv from 16.5.0 to 16.6.1
- Updated express from 5.1.0 to 5.2.1
- Updated @types/express from 5.0.1 to 5.0.6
- Updated @types/node from 22.15.17 to 22.19.3
- Updated @types/socket.io from 3.0.1 to 3.0.2
- Updated concurrently from 9.1.2 to 9.2.1
- Updated typescript from 5.9.2 to 5.9.3
2025-12-17 11:01:01 +01:00
Carlos Santos
7c75a9ddd0 frontend: reorder imports and add type annotation for currentTheme computed property 2025-12-17 10:08:37 +01:00
Carlos Santos
4d3adc1922 frontend: remove unused webpack configuration file 2025-12-16 18:23:19 +01:00
Carlos Santos
d925cb7843 frontend: refactor step indicator layout for improved responsiveness and structure 2025-12-16 17:58:32 +01:00
Carlos Santos
59ea1f881b frontend: rename DEFAULT_MAX_SPEAKERS to INITIAL_SPEAKERS_COUNT and adjust max speakers for mobile devices 2025-12-16 12:42:42 +01:00
Carlos Santos
d059872667 frontend: remove deprecated end-to-end tests and configuration files 2025-12-16 12:04:45 +01:00
Carlos Santos
bd1c67ba31 Add test suite documentation for OpenVidu Meet 2025-12-16 12:04:34 +01:00
Carlos Santos
f178f2a611 frontend: Increase minimum speaking duration for smart layout display to enhance participant tracking 2025-12-11 13:50:25 +01:00
Carlos Santos
477119a06f frontend: Updated livekit client js 2025-12-11 10:09:59 +01:00
Carlos Santos
cbe07bcf4f frontend: Remove redundant visibility checks for speakers in custom layout tests 2025-12-10 17:16:23 +01:00
Carlos Santos
34f50d0dee frontend: Add wait timeout for virtual background application in tests 2025-12-10 15:58:15 +01:00
Carlos Santos
9ff200fa88 frontend: Add test for hiding audio-muted participants in Smart Mosaic layout 2025-12-10 11:10:10 +01:00
Carlos Santos
d7cefdfd47 frontend: Update E2E tests to handle optional event text and clean up imports 2025-12-09 12:19:17 +01:00
Piwccle
c93b369a4f
Update GCS bucket name in integration test workflow 2025-12-05 15:18:16 +01:00
Carlos Santos
cf3f03bf3c ci: Add LK CLI installation step to E2E test workflow
test: Introduce wait timeout before leaving the room in tests
2025-12-05 12:10:34 +01:00
Carlos Santos
2761e68dd8 backend: Implement room status validation and cleanup for active meetings 2025-12-05 11:49:14 +01:00
Carlos Santos
a3d4fda6ae frontend: Adds tests for Smart Mosaic layout 2025-12-04 19:42:44 +01:00
Carlos Santos
1abdc45ff3 frontend: Enhances custom layout screen sharing
Ensures screen sharing participants are always displayed, even if not active speakers.

Modifies the participant proxy to selectively hide camera tracks when a participant is only displayed for screen sharing.
This prevents unnecessary camera rendering in the custom layout.
2025-12-04 19:41:58 +01:00
Carlos Santos
5ef051658a frontend: Enhances smart mosaic layout
Improves the smart mosaic layout to enhance the user experience and performance.

- Updates participant rendering logic for smart mosaic layout.
- Optimizes audio track management to prevent audio leaks.
- Implements audio focus by selectively muting tracks for inactive speakers.
2025-12-04 17:30:25 +01:00
Carlos Santos
c51a5173dd root: Enables organize imports on save
Configures the IDE to automatically organize imports upon saving files.

This enhances code cleanliness and consistency by ensuring imports are
automatically sorted and unnecessary imports are removed.
2025-12-04 16:52:58 +01:00
Carlos Santos
07b22a0d29 Refactors room parameter extraction
Streamlines parameter handling by centralizing logic.
The `RoomService` is no longer responsible for setting the `roomId` and `roomSecret`.
Instead, the `MeetingContextService` handles this and persists the room secret in session storage.
2025-12-03 18:01:58 +01:00
Carlos Santos
1663b008ed frontend (test): add Smart Mosaic layout helper functions and fake participant management
- Implemented helper functions for configuring Smart Mosaic layout, including setting participant count and waiting for participant visibility.
- Created a new file for managing fake participants, allowing for joining and disconnecting from LiveKit rooms using both CLI and browser-based methods.
- Introduced interfaces for browser-based fake participant options to streamline participant creation with audio and video assets.
2025-12-02 21:02:40 +01:00
Carlos Santos
f930bf1447 frontend: Exposes and provides layout service
Exposes the layout and storage services from the shared components library.

Provides the layout service to make it available for dependency injection.
2025-12-02 21:01:12 +01:00
Carlos Santos
8e9443351c frontend: Improves active speaker detection
Refines active speaker detection for smart layouts.

It now considers audio level threshold, minimum speaking duration, and a grace period to avoid rapid speaker switching.

Also, updates the speaker recency order to prioritize currently active speakers while maintaining a history of recent speakers.
2025-12-02 21:00:33 +01:00
juancarmore
6c7bfd4d3f openapi: add accessUrl field to room schema and update success responses that include room info 2025-12-02 14:18:39 +01:00
Carlos Santos
68c5ce7cd2 frontend: Refactors layout and feature configurations
Consolidates layout management into a dedicated component and service.

- Replaces layout selection logic with feature-based approach.
- Improves code readability and maintainability.
2025-12-01 16:55:54 +01:00
juancarmore
5638025211 Refactor OpenAPI components for user and room management
- Updated user login request body to define username and password directly instead of referencing an external schema.
- Removed obsolete recording token request schema.
- Added new request body for updating room anonymous access configuration.
- Deleted outdated room guests request body.
- Enhanced room member request body documentation for clarity on custom permissions.
- Introduced new request body for updating room roles configuration.
- Added error response schema for user ID already exists.
- Created success response schema for retrieving authenticated user info.
- Modified success response for retrieving multiple users to use userId instead of username.
- Updated success response for room members to reflect changes in memberId and access URLs.
- Adjusted success response for room details to include roles instead of guests.
- Created success response for updating room anonymous access configuration.
- Created success response for updating room roles configuration.
- Revised meet-user schema to use userId instead of username and simplified role representation.
- Deleted obsolete user-credentials schema.
- Introduced meet-room-anonymous-config schema for anonymous access configuration.
- Removed obsolete meet-room-guests schema.
- Updated meet-room-member schema to clarify memberId and name usage.
- Revised meet-room schema to replace guests with roles and added anonymous access configuration.
- Updated OpenAPI paths to reflect changes in user and room management endpoints.
2025-12-01 13:50:27 +01:00
juancarmore
da7759d249 openapi: add specification for user management API with create, retrieve and delete user endpoints 2025-11-28 13:31:37 +01:00
juancarmore
ba374ce229 openapi: standardize 'username' field naming and update related descriptions for room member APIs 2025-11-28 12:41:22 +01:00
juancarmore
cf84de4221 openapi: remove deprecated room member roles and permissions endpoints and related schemas 2025-11-28 12:30:43 +01:00
juancarmore
39a9b7da02 openapi: add room guests management API with update permissions for moderator and speaker roles 2025-11-28 12:17:24 +01:00
juancarmore
e990c19672 openapi: add specification for room member management API with add, update, delete, and retrieve endpoints 2025-11-28 11:19:59 +01:00
Carlos Santos
66b7f6026b frontend: Enhances smart mosaic layout configuration
Allows configuring the number of visible participants in Smart Mosaic layout mode using a slider.

The minimum and maximum number of participants are now configurable via constants.

Updates the slider to use value binding instead of ngModel.
2025-11-27 12:30:38 +01:00
Carlos Santos
21971e1895 frontend: enhance E2EE key input handling with computed visibility and raw value access 2025-11-27 09:33:20 +01:00
cruizba
246d6e91a4 docker: add tzdata installation to Dockerfiles for timezone support 2025-11-26 11:12:42 +01:00
Carlos Santos
d20571b0ef frontend: enable layout selector feature for smart layout configuration 2025-11-25 13:57:09 +01:00
Carlos Santos
f6abd1cb4c frontend: Refactor customization components
Moves the copy link button to a new component for additional toolbar buttons.

This allows for better organization and customization of the toolbar,
especially on mobile where space is limited. The "leave" button for
moderators is now separate.

Renamed components for better understanding and readability
2025-11-25 13:55:45 +01:00
Carlos Santos
bd021c9576 frontend: implement layout selector feature with conditional rendering in settings and toolbar 2025-11-25 13:55:45 +01:00
Carlos Santos
c3ca84ad66 frontend: remove unused meeting components plugins and action handler interfaces 2025-11-25 13:55:45 +01:00
Carlos Santos
153af9c673 frontend: enhance layout management with reactive settings and storage integration 2025-11-25 13:55:45 +01:00
Carlos Santos
c8cfb6598e frontend: add meeting settings panel and more options buttons for layout configuration 2025-11-25 13:55:45 +01:00
Carlos Santos
b177b3b02e frontend: update no rooms state message and styling for better user guidance 2025-11-25 13:55:45 +01:00
Carlos Santos
f83a5d8942 frontend: adjust margin-bottom for recordings toolbar to improve spacing 2025-11-25 13:55:45 +01:00
Carlos Santos
40475dc372 frontend: use content projection for configuring videoconference components
Refactored all components and services related to the meeting
2025-11-25 13:55:45 +01:00
Carlos Santos
fd998e7b6b frontend: implement MeetingLayoutComponent with reactive layout management and active speakers tracking 2025-11-25 13:55:44 +01:00
juancarmore
8ccc5d1a8b test: refactor code in tests for garbage collection of orphaned locks, stale recordings and expired rooms 2025-11-24 20:17:10 +01:00
juancarmore
f71b567823 backend: extract shceduler methods from RoomService and RecordingService and create RoomScheduledTasksService and RecordingScheduledTasksService for managing scheduled tasks 2025-11-24 20:14:25 +01:00
juancarmore
a9360ef452 backend: refactor recording access secret retrieval to use RecordingService 2025-11-23 21:47:46 +01:00
juancarmore
3aaf976964 backend: add new methods to global config service and refactor code for improved clarity 2025-11-23 21:18:42 +01:00
juancarmore
73813feb38 backend: rename and refactor various schemas and functions 2025-11-23 20:30:50 +01:00
juancarmore
bdbc6d02ad test: update orphaned lock age in garbage collector tests for accuracy 2025-11-23 17:46:15 +01:00
juancarmore
848cf2ca17 test: refactor stale recordings cleanup tests for improved clarity and functionality 2025-11-23 17:23:53 +01:00
juancarmore
49b44d0353 backend: remove unnecessary index files and update import paths 2025-11-23 17:23:53 +01:00
juancarmore
0d6838019d backend: enhance recording management with active recordings retrieval and stale cleanup improvements 2025-11-23 17:23:52 +01:00
juancarmore
253b435fbe backend: add SERVER_TRUST_PROXY configuration for flexible proxy handling 2025-11-23 17:23:52 +01:00
juancarmore
447a1fc9e5 backend: refactor internal configuration and service tasks for improved room and recording management 2025-11-23 17:23:52 +01:00
juancarmore
5234b28917 backend: update environment variable defaults to use nullish coalescing operator 2025-11-23 17:23:52 +01:00
juancarmore
69df748002 backend: refactor code to centralize all TS interfaces, types, enums and schemas under the models directory 2025-11-23 17:23:52 +01:00
cruizba
b711840349 ci: update workflows to use LABEL_WORKER_SELFHOSTED var 2025-11-19 20:08:24 +01:00
cruizba
69399bb2ff meet-demo: remove Caddyfile reference from deployment README 2025-11-19 17:53:24 +01:00
cruizba
77528b28f4 meet-demo: remove Caddyfile and update docker-compose to use auto-https image 2025-11-19 17:51:57 +01:00
juancarmore
fad38b696d backend: refactor environment variable usage across services and tests 2025-11-18 18:43:05 +01:00
juancarmore
e3fe104b05 backend: enhance login limiter configuration for better proxy compatibility and adjust base URL middleware condition 2025-11-18 17:41:36 +01:00
juancarmore
4f9116707c frontend: update room configuration methods to accept partial configurations and improve handling of optional properties 2025-11-18 14:22:02 +01:00
juancarmore
3f25ba6f74 test: update room configuration methods to accept partial configurations and enhance related tests 2025-11-18 14:20:33 +01:00
juancarmore
496591695a backend: update room configuration schemas for partial updates and default values 2025-11-18 14:19:56 +01:00
juancarmore
45ee463bc6 backend: enhance migration service to handle existing records and track failures 2025-11-18 14:02:03 +01:00
juancarmore
3ae55d0814 backend: add delete method for global configuration and skip initialization if already set 2025-11-18 11:38:42 +01:00
juancarmore
f74b50d5c8 docs: update README to reflect MongoDB storage architecture and migration system 2025-11-18 10:59:09 +01:00
juancarmore
0f237af827 backend: implement MongoDB schema migration system
- Added internal configuration for schema versions in internal-config.ts.
- Created migration README.md to document the migration process and architecture.
- Developed base migration class and specific migration files for each collection (API key, global config, room, recording, user).
- Established migration registry to manage and execute migrations in order.
- Updated repository schemas to include schemaVersion for migration tracking.
- Enhanced migration service to orchestrate schema migrations and handle migration execution.
2025-11-18 10:27:26 +01:00
juancarmore
e30aa5f1a5 backend: update sanitizeRoomId to allow uppercase letters in identifiers 2025-11-17 14:47:28 +01:00
juancarmore
f62e59168d test: update non-existent IDs format in bulk delete recording and room tests 2025-11-17 13:46:58 +01:00
juancarmore
99283ab63d test: update room member token response tests to use participant identity prefix 2025-11-14 20:34:02 +01:00
juancarmore
6b3ef47f08 backend: enhance participant identity handling by creating a unique identity based on participant name 2025-11-14 20:33:48 +01:00
juancarmore
152a877054 test: enhance room creation tests with additional sanitization cases and roomId prefix validation 2025-11-14 19:14:57 +01:00
juancarmore
3665c70105 backend: update room validators to admit all types of characters in the room name and add room ID prefix sanitization method to create roomId from room name 2025-11-14 19:14:00 +01:00
juancarmore
294bd1b7ec frontend: update error messages for invalid room and recording links in ErrorComponent 2025-11-14 12:55:49 +01:00
juancarmore
8d12105b91 ci: fix report and log paths in backend and E2E test workflows 2025-11-14 12:18:44 +01:00
Piwccle
28b58a80bf fix: update GCS bucket name to openvidu-appdata-gcp in backend integration tests 2025-11-14 12:04:18 +01:00
juancarmore
a518b16b6b ci: update artifact path in backend integration test workflow 2025-11-14 11:34:36 +01:00
juancarmore
6eb33c6198 Delete participant and recording tokens and implement room member token. Remove unused cookie transport mode for tokens 2025-11-14 11:23:25 +01:00
Carlos Santos
a56a119993 frontend: correct property name for virtual backgrounds in RoomConfigComponent 2025-11-13 13:51:40 +01:00
Carlos Santos
26bc6cdfc1 backend: improve documentation for stale recording evaluation logic 2025-11-13 10:50:22 +01:00
Carlos Santos
f3de3e0fa3 test: update leaveRoom calls to include optional parameters for role and force leave 2025-11-12 18:14:03 +01:00
Carlos Santos
72119685ad frontend: remove build:ov-components from build script 2025-11-12 16:56:54 +01:00
Carlos Santos
84b74ea0f3 frontend: update livekit-client version to 2.15.15 in package.json and pnpm-lock.yaml 2025-11-12 12:00:43 +01:00
Carlos Santos
9fe20f6e87 build: enhance clean script to remove pnpm-lock.yaml and add clean:ov-components 2025-11-12 11:22:57 +01:00
Carlos Santos
27094be54e test: enhance leaveRoom function to optionally wait for meeting to end 2025-11-11 20:40:53 +01:00
Carlos Santos
d377b016e2 tests: update log level to debug and remove commented timeout in tests 2025-11-11 19:53:18 +01:00
Carlos Santos
5b94728bc9 baackend: allow meeting timeouts to be set via environment variables 2025-11-11 19:53:00 +01:00
Carlos Santos
5131f9e717 test: reduce wait time for recording tests and improve cleanup process 2025-11-11 19:43:23 +01:00
Carlos Santos
32a9a31d8b test: disconnect all participants for allowing update room 2025-11-11 18:16:46 +01:00
Carlos Santos
ae5907cbbd meet.sh: add webcomponent bundle watcher to development commands 2025-11-11 16:55:17 +01:00
Carlos Santos
d9a31edb60 frontend: update livekit-client dependency to version 2.15.15 2025-11-11 16:27:24 +01:00
Carlos Santos
d3554aa6cb backend: fixed unique name reservation logic to prevent infinite suffix concatenation 2025-11-11 16:12:54 +01:00
Carlos Santos
3ec9b43ce4 test: add tests for unique name reservation edge cases 2025-11-11 16:04:24 +01:00
Carlos Santos
253ad630c7 backend: set default timeouts for meeting empty and departure scenarios 2025-11-11 14:02:27 +01:00
Carlos Santos
d72149c97d Prevents editing rooms with active meetings
Enhances room management by preventing modifications to rooms with active meetings.

Adds validation to backend to prevent updates to room configuration during an active meeting.

Improves frontend user experience by disabling the room editing option and adding a guard to redirect users away from the edit page.
2025-11-11 14:00:00 +01:00
Carlos Santos
449f9cbf25 Merge branch 'e2ee_feature' 2025-11-10 17:55:10 +01:00
Carlos Santos
b055ef0333 update file exclusion patterns in workspace settings
webcomponent: Added missing and necessary js file

Update .gitignore to specify backend public directory exclusion

webcomponent: Add error handling for invalid base URL in OpenViduMeet component

webcomponent: Update Jest configuration for improved testing setup

webcomponent: Enhance iframe attribute tests and add support for optional query parameters

webcomponent: Refactor documentation copying in build_webcomponent_doc function for improved readability and add absolute path resolution

Add E2EE_KEY property to WebComponentProperty enum for end-to-end encryption support

meet.sh: Enhance build_rest_api_doc function with output file handling and user confirmation for overwriting

frontend: replace removeRoomSecretGuard with removeQueryParamsGuard for enhanced query parameter management

frontend: add E2EE key handling in room service and update query params guard

Updated pnpm-lock.yaml

Enables end-to-end encryption (E2EE)

Adds E2EE functionality to meeting rooms.

Significant changes:
- Allows encryption of the participant name
- Introduces setting and getting E2EE keys
- Ensures recording is disabled when encryption is enabled

webcomponent: Added e2e test for checking the e2ee funcionality

frontend: Sanitize participant name before request for a token

fix: clean up formatting in openvidu-meet.code-workspace
2025-11-10 17:54:33 +01:00
juancarmore
1d55311757 test: enhance type safety in request helpers 2025-11-07 09:59:55 +01:00
juancarmore
d52524241f test: add test for handling expired access token with valid participant token 2025-11-06 17:49:04 +01:00
juancarmore
3fdf2144ab backend: streamline authentication validators and improve error handling 2025-11-06 17:48:46 +01:00
juancarmore
e6d04aca16 Migrate storage from S3 to MongoDB:
commit 7fc703b7a01c038cfff69c88fea5d681b3011ea1
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Nov 5 17:45:06 2025 +0100

    backend: add E2EE configuration schema to MeetRoom

commit 3ad51133aaa696c36b9fc5dd1c271b5e09077e0b
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Nov 5 16:15:13 2025 +0100

    backend: enhance MongoDB configuration logging and validation

commit b5b52e97dd4a0e16dbb5cda53dc406aa5c739380
Author: cruizba <carlos.ruizbal@gmail.com>
Date:   Wed Nov 5 15:50:05 2025 +0100

    feat: add MongoDB configuration options for optional mongodb and configurable uri

commit c6f0c35435a18365c99f44c692d5d2f2a9bd53ab
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Nov 5 13:59:10 2025 +0100

    ci: update backend integration test scripts and workflow

commit 19a1348f2f695a27694f1c5e80de696d039b6f4e
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 31 12:05:38 2025 +0100

    frontend: replace AuthService with ApiKeyService for API key management

commit 9465e40bc1babfae1203dc317907dc86dc57cd0c
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 31 12:05:07 2025 +0100

    test: refactor auth and api key tests structure to improve consistency

commit b154aa8186eaaa51e027fc1459b9175f87affbd8
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 31 12:02:42 2025 +0100

    openapi: move API key management endpoints to a dedicated file and update references

commit 6987d2b587d1cd6ba85f2ea38c408957e5f0de04
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 31 12:01:00 2025 +0100

    backend: move API key management endpoints to its own controller

commit 8c9452bb74887265920942e3253921a43504790b
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 31 12:00:00 2025 +0100

    backend: comment out MigrationService import and related export to prevent initialization error

commit daa923fa9f6ee68cb4f4ebfa61ce16026fbdc374
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 23:09:18 2025 +0100

    backend: implement migration service

commit 058593fb9488ae00077e28a591c7ea2a8b8d96cc
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 23:08:05 2025 +0100

    backend: add migration repository and model to handle database migrations

commit 4cbc9a9f48ede801333bfe37f0dba2993a79c29c
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 19:41:01 2025 +0100

    backend: refactor update repository methods to throw errors instead of returning null for not found cases

commit 03496a733b9fa39776eb4bf70057459c7e567954
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 17:55:42 2025 +0100

    openapi: update roomName parameter description and reference in recordings path

commit 74293e04967fb1416b69324294ae864df9173f91
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 17:55:04 2025 +0100

    openapi: add analytics endpoint and schema for usage metrics

commit 8de171b0b340ffa787ef136a3e516f03f96b1938
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 17:40:24 2025 +0100

    test: add analytics API and corresponding security tests

commit aaa15acdda5f09c6c0e45d24385cc9ec5daca55b
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 14:04:58 2025 +0100

    frontend: implement analytics service and update overview component to use new metrics

commit 13bad60bcc02e9d7aa46fc9bb96f7cc85ec818cc
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 14:04:23 2025 +0100

    backend: add analytics endpoint for usage metrics

commit ee820bba27f421bb2f9d34130bc00b41aefad217
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 13:18:29 2025 +0100

    backend: replace z.enum with z.nativeEnum for improved type safety in validation schemas

commit 1d394d059e6beef47faddd2205482974ecc1860c
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Thu Oct 30 11:50:03 2025 +0100

    backend: update MongoDB configuration to use new environment variables and improve connection string handling

commit 56c0c3a1bd19bbd2a5e0fdbe582fdf288c6f33d1
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 18:23:06 2025 +0100

    frontend: update room ID reference in recording lists component

commit 189d1b26ad18d29cf9f7c6f85c2524ed5ad33f72
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 18:12:07 2025 +0100

    tests: remove unused MeetStorageService references and related tests

commit fe3fcdba35afcf186b0ff05e9ec3b2ae05da1005
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 17:31:18 2025 +0100

    backend: rename MeetStorageService to LegacyStorageService and remove all unused methods

commit fa782f234d561b5f7f6d4a50e54e3278b9beaec4
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 15:56:31 2025 +0100

    backend: replace MeetStorageService with RecordingRepository and BlobStorageService for recording management

commit 51dea37c07e477bc7e447b2e57acd21b44deb5e4
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 15:53:48 2025 +0100

    frontend: add roomName filter to recording service and recordings component

commit fa283e7c51b3382300cb25fa5f8a9e144637c757
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 15:53:04 2025 +0100

    backend: add roomName filter in get recordings endpoint

commit d1dfb24cfda2e22d739f506bf0213275cd4b2bdd
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 15:51:00 2025 +0100

    backend: implement BlobStorageService for managing recording media files in object storage

commit ce293cf37545fa3aaad638eb25dfd9ae5fc8dd72
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 15:48:04 2025 +0100

    backend: add unique index for efficient querying on MeetApiKey and MeetGlobalConfig schemas

commit 3d999b4249e15f63ef086d2ab38485e0fbadb27e
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Wed Oct 29 15:47:44 2025 +0100

    backend: add RecordingRepository and schema for managing recording entities

commit 757636c55254e76643b99a66bc583ab834c5eadd
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Tue Oct 28 13:05:12 2025 +0100

    tests: refactor list rooms with pagination test to create rooms sequentially and ensure correct ordering

commit cda25543e30883431962bef8617cb245eade8a1d
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Tue Oct 28 13:04:32 2025 +0100

    tests: centralize method restoreDefaultGlobalConfig and refactor code

commit 726d128d7471ad4abbaabda086304f22705ddf82
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Tue Oct 28 13:01:17 2025 +0100

    backend: enhance GlobalConfig schema with authentication, security, webhook, and room configuration sub-schemas

commit fd49fbb03cd8d70f29cc5781a0e0b9b5244f4747
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Tue Oct 28 11:02:34 2025 +0100

    backend: add StorageInitService for managing storage initialization and refactor dependency injection

commit 783f480337e61bfc19ad6d19f3b84c523577c309
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Tue Oct 28 11:01:58 2025 +0100

    backend: refactor middleware and services to use GlobalConfigService for configuration management

commit d28247647c2e0712c0575faa8a85a8c67a75f343
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 22:23:40 2025 +0100

    backend: move authenticateUser method to UserService and rename AuthService to ApiKeyService

commit c8f98391a178da4f9525069203fe4e3d2aecfaaa
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 22:21:37 2025 +0100

    backend: implement GlobalConfigService for managing global configuration and update related controllers

commit 08421feffc8cd4cadb8f2df3b4c41169d4776572
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 22:20:23 2025 +0100

    backend: add GlobalConfigRepository and schema for managing global configuration

commit e1e1b0dda511fb5fbdd8fc88f8a691bc974866c9
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 13:53:52 2025 +0100

    backend: refactor AuthService and MeetStorageService to use ApiKeyRepository for API key management

commit c46fd1669d0923a63195ef95ddf3105584fc18fc
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 13:52:56 2025 +0100

    backend: add ApiKeyRepository and schema for managing API keys

commit c1220eb89b98e842009fd16d95ddd87fd87ae02c
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 13:52:27 2025 +0100

    backend: rename UserDocument and UserModel to MeetUserDocument and MeetUserModel for consistency

commit 331e4ca264086e4fd0e947f2c8adc04dbfe7f831
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 12:27:43 2025 +0100

    backend: replace MeetStorageService usage with UserRepository in UserService

commit ec074307c3cd8c30f4babef5194fc4ebbe7ea7c0
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 12:05:15 2025 +0100

    test: update startTestServer calls to await for asynchronous initialization

commit 3bba2e2822824a1855e6691c0c3b456c9ac5dd3a
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Mon Oct 27 12:04:39 2025 +0100

    test: initialize eager services in startTestServer and update calls to await for asynchronous initialization

commit e52f7353515f95835c9d15dba41ff33a2e26d367
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 24 19:40:04 2025 +0200

    backend: add User schema and repository for user management

commit 10c548afa9e45dd72d0fb86c9dab0a601c08e652
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 24 19:39:38 2025 +0200

    backend: add findAll method to BaseRepository and findExpiredRooms method to RoomRepository

commit cbe467e0e5475311f8aea4b4ff99a481007537c0
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 24 19:39:09 2025 +0200

    backend: optimize MeetRoom schema by adding indexes for efficient querying

commit fb95ef3248e64721e107c3c019e6a61a210ad6ce
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 24 18:07:38 2025 +0200

    backend: enhance cursor-based pagination to handle null/undefined values in MongoDB queries

commit bf709bb8e4a301a5738e44c7d7fb2f219846c3ce
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 24 18:07:25 2025 +0200

    ci: update integration test paths to reflect new directory structure

commit 67ce9da156dccded23eb2b9b9a8a34c835d7f27b
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 24 15:09:21 2025 +0200

    backend: replace storage service with RoomRepository for room management

commit 25dcd057d6597910fa4992dc45934e85edbd6a3e
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 24 15:07:55 2025 +0200

    backend: implement RoomRepository to manage MeetRoom objects in MongoDB

commit 42e6036741871b964d9d7a644210eedeaf1ad543
Author: juancarmore <juancar_more2@hotmail.com>
Date:   Fri Oct 24 15:05:31 2025 +0200

    backend: add mongoose dependecy and create MongoDBService
2025-11-05 17:48:38 +01:00
Carlos Santos
684d575c08 frontend: Fixed error with basic creation room 2025-11-05 17:43:47 +01:00
Carlos Santos
7dd368476e Merge branch 'e2ee_feature' 2025-11-05 17:11:51 +01:00
Carlos Santos
fd905286a6 typings: add E2EE configuration interface to MeetRoomConfig
frontend: add End-to-End Encryption (E2EE)

- Updated meeting lobby and room wizard components to handle E2EE settings.
- Added E2EE configuration options in the room wizard and lobby services.
- Implemented validation for E2EE key input in participant forms.
- Enhanced UI to reflect E2EE restrictions on recording and streaming.
- Added animations for E2EE warning and info sections.

backend: Added E2EE configuration and middleware

backend: Added e2ee configuration property to openapi

Enables E2EE functionality

Configures the application to support end-to-end encryption (E2EE).

Copies the necessary worker script to the assets folder.

Passes the E2EE key to the meeting component.

Adds a script to remove node_modules and dist folder.

frontend: Add E2EE UI tests and configuration options

webcomponent: Ensure cleanup of test environment after moderation tests

frontend: Update E2EE description and restrictions

webcomponent: Enhance E2EE UI tests by adding participant interactions and verifying visibility with correct keys

backend: Updated start recording example response
2025-11-05 17:11:30 +01:00
721 changed files with 32422 additions and 21097 deletions

View File

@ -141,8 +141,6 @@
**/*.mov
**/*.mkv
**/*.webm
**/*.mp3
**/*.wav
**/*.flac
# ====================================================

View File

@ -1,49 +0,0 @@
# CONFIGURACIÓN PARA EASYPANEL + LIVEKIT SELF-HOSTED
# ===========================================
# CONFIGURACIÓN BÁSICA
# ===========================================
NODE_ENV=production
MEET_LOG_LEVEL=info
MEET_BLOB_STORAGE_MODE=memory
# ===========================================
# USUARIO ADMINISTRADOR
# ===========================================
ADMIN_USER=admin
ADMIN_PASSWORD=admin123
# ===========================================
# LIVEKIT SELF-HOSTED (RED LOCAL + PÚBLICO)
# ===========================================
# ✅ LiveKit corriendo en servidor dedicado
# ✅ Puertos UDP expuestos en router
# ✅ SSL/WSS configurado
# URL de tu LiveKit self-hosted (cambiar por tu dominio/IP)
LIVEKIT_URL=wss://mi-livekit.duckdns.org
# O con IP fija: wss://TU_IP_PUBLICA:443
LIVEKIT_API_KEY=production-key
LIVEKIT_API_SECRET=tu-super-secret-de-32-caracteres-o-mas
# ===========================================
# REDIS (OPCIONAL para EasyPanel)
# ===========================================
# Si quieres Redis también en EasyPanel
# REDIS_HOST=redis
# REDIS_PORT=6379
# REDIS_PASSWORD=admin-redis
# ===========================================
# ARQUITECTURA FINAL:
# ===========================================
# Internet → Router (Port Forward) → LiveKit Server (192.168.1.19)
# ↘ EasyPanel → OpenVidu Meet Backend
#
# Ventajas:
# ✅ Control total sobre LiveKit
# ✅ Sin costos mensuales externos
# ✅ Rendimiento en red local
# ✅ Acceso desde internet
# ✅ Escalable según hardware

View File

@ -2,14 +2,14 @@ name: Backend Integration Tests
on:
push:
paths:
- 'backend/src/**'
- 'backend/package.json'
- 'backend/pnpm-lock.yaml'
- 'backend/tests/**'
- 'meet-ce/backend/src/**'
- 'meet-ce/backend/package.json'
- 'pnpm-lock.yaml'
- 'meet-ce/backend/tests/**'
- '.github/workflows/backend-integration-test.yaml'
pull_request:
paths:
- 'backend/src/**'
- 'meet-ce/backend/src/**'
workflow_dispatch:
inputs:
use-aws:
@ -22,7 +22,7 @@ on:
jobs:
build-components:
name: Build OpenVidu Components Angular
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
steps:
- name: Build Components
id: build
@ -33,26 +33,19 @@ jobs:
test-api:
name: ${{ matrix.test-name }}
needs: build-components
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
strategy:
fail-fast: false
matrix:
include:
- test-name: 'Rooms API Tests'
test-script: 'test:integration-backend-rooms'
- test-name: 'Room Management API Tests (Rooms, Meetings)'
test-script: 'test:integration-backend-room-management'
- test-name: 'Webhook Tests'
test-script: 'test:integration-backend-webhooks'
- test-name: 'Security API Tests'
test-script: 'test:integration-backend-security'
azure-container: 'openvidu-appdata-security'
- test-name: 'Global Config API Tests'
test-script: 'test:integration-backend-global-config'
- test-name: 'Participants API Tests'
test-script: 'test:integration-backend-participants'
- test-name: 'Meetings API Tests'
test-script: 'test:integration-backend-meetings'
- test-name: 'Users API Tests'
test-script: 'test:integration-backend-users'
- test-name: 'Auth & Security API Tests (Security, Auth, API Keys, Users)'
test-script: 'test:integration-backend-auth-security'
- test-name: 'Config & Analytics API Tests (Global Config, Analytics)'
test-script: 'test:integration-backend-config-analytics'
steps:
- name: Install LK CLI
run: curl -sSL https://get.livekit.io/cli | bash
@ -85,13 +78,11 @@ jobs:
with:
build_components_angular: 'true'
components_artifact_name: ${{ needs.build-components.outputs.artifact_name }}
env:
MEET_AZURE_CONTAINER_NAME: ${{ matrix.azure-container || '' }}
- name: Run tests
run: pnpm run ${{ matrix.test-script }}
env:
JEST_JUNIT_OUTPUT_DIR: './backend/reports/'
JEST_JUNIT_OUTPUT_DIR: './meet-ce/backend/reports/'
- name: Upload OpenVidu Meet logs
if: failure()
@ -115,7 +106,7 @@ jobs:
start-aws-runner-s3:
name: Prepare AWS runner (S3)
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
if: ${{ inputs.use-aws != 'false' }}
outputs:
label: ${{ steps.start-ec2-runner.outputs.label }}
@ -138,7 +129,7 @@ jobs:
start-aws-runner-abs:
name: Prepare AWS runner (ABS)
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
if: ${{ inputs.use-aws != 'false' }}
outputs:
label: ${{ steps.start-ec2-runner.outputs.label }}
@ -161,7 +152,7 @@ jobs:
start-aws-runner-gcs:
name: Prepare AWS runner (GCS)
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
if: ${{ inputs.use-aws != 'false' }}
outputs:
label: ${{ steps.start-ec2-runner.outputs.label }}
@ -190,7 +181,7 @@ jobs:
- start-aws-runner-gcs
- build-components
if: ${{ always() && (needs.start-aws-runner-s3.result == 'success' || needs.start-aws-runner-s3.result == 'skipped') && (needs.start-aws-runner-abs.result == 'success' || needs.start-aws-runner-abs.result == 'skipped') && (needs.start-aws-runner-gcs.result == 'success' || needs.start-aws-runner-gcs.result == 'skipped') }}
runs-on: ${{ (matrix.storage-provider == 's3' && needs.start-aws-runner-s3.outputs.label) || (matrix.storage-provider == 'abs' && needs.start-aws-runner-abs.outputs.label) || (matrix.storage-provider == 'gcs' && needs.start-aws-runner-gcs.outputs.label) || 'ov-actions-runner' }}
runs-on: ${{ (matrix.storage-provider == 's3' && needs.start-aws-runner-s3.outputs.label) || (matrix.storage-provider == 'abs' && needs.start-aws-runner-abs.outputs.label) || (matrix.storage-provider == 'gcs' && needs.start-aws-runner-gcs.outputs.label) || vars.LABEL_WORKER_SELFHOSTED }}
strategy:
fail-fast: false
matrix:
@ -292,7 +283,7 @@ jobs:
- name: Run tests
run: pnpm run test:integration-backend-recordings
env:
JEST_JUNIT_OUTPUT_DIR: './backend/reports/'
JEST_JUNIT_OUTPUT_DIR: './meet-ce/backend/reports/'
MEET_BLOB_STORAGE_MODE: ${{ matrix.storage-provider }}
# ABS variables
MEET_AZURE_ACCOUNT_NAME: ${{ matrix.storage-provider == 'abs' && vars.MEET_AZURE_ACCOUNT_NAME || '' }}
@ -315,7 +306,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: recordings-test-${{ matrix.storage-provider }}-openvidu-meet-logs
path: backend/meet_backend.log
path: meet_backend.log
retention-days: 2
- name: Clean up credentials
@ -335,7 +326,7 @@ jobs:
- start-aws-runner-abs
- start-aws-runner-gcs
- test-recordings
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
if: ${{ always() }}
strategy:
fail-fast: false
@ -359,7 +350,7 @@ jobs:
- build-components
- test-api
- test-recordings
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
if: ${{ always() }}
steps:
- name: Remove Artifact

View File

@ -7,7 +7,7 @@ on:
jobs:
unit-test:
name: Backend Unit Tests
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
steps:
- name: Setup Node.js
uses: actions/setup-node@v5

View File

@ -7,7 +7,7 @@ on:
jobs:
e2e-tests:
name: WebComponent E2E Tests
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
steps:
- name: Setup Node.js
uses: actions/setup-node@v5
@ -17,6 +17,8 @@ jobs:
uses: pnpm/action-setup@v4
with:
version: 10.18.3
- name: Install LK CLI
run: curl -sSL https://get.livekit.io/cli | bash
- name: Setup OpenVidu Local Deployment
uses: OpenVidu/actions/start-openvidu-local-deployment@main
with:
@ -56,7 +58,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: room-test-results
path: frontend/webcomponent/test-results/
path: meet-ce/frontend/webcomponent/test-results/
retention-days: 2
- name: Upload TestApp logs on failure
@ -64,7 +66,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: room-test-testapp-logs
path: testapp/testapp.log
path: testapp.log
retention-days: 2
- name: Upload OpenVidu Meet logs on failure
@ -72,7 +74,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: room-test-openvidu-meet-logs
path: backend/meet_backend.log
path: meet_backend.log
retention-days: 2
- name: Clean up

View File

@ -7,7 +7,7 @@ on:
jobs:
unit-test:
name: WebComponent Unit Tests
runs-on: ov-actions-runner
runs-on: ${{ vars.LABEL_WORKER_SELFHOSTED }}
steps:
- name: Setup Node.js
uses: actions/setup-node@v5

2
.gitignore vendored
View File

@ -37,7 +37,7 @@ pnpm-debug.log*
**/**/test-results
**/**/public/
**/backend/public/
**/*/coverage
**/**/test-results

13
.npmrc
View File

@ -1,18 +1,10 @@
# Docker/CI specific npm configuration
# This configuration is used during Docker builds and CI workflows
# to prevent linking workspace packages and use published versions instead
# Disable workspace package linking
# This forces pnpm to install packages from registry or local tarballs
link-workspace-packages=false
# Strict peer dependencies
strict-peer-dependencies=false
# Auto install peers
auto-install-peers=true
# Shamefully hoist - necessary for some packages
# Shamefully hoist - neccessary for some packages
shamefully-hoist=true
# Node linker - use hoisted for full compatibility
@ -20,3 +12,6 @@ node-linker=hoisted
# Lockfile settings
lockfile=true
# Optional: Store location (uncomment if you want to customize)
# store-dir=.pnpm-store

View File

@ -1,65 +0,0 @@
# CLOUDFLARE TUNNEL - SIN PORT FORWARDING
## ☁️ Cloudflare Tunnel para LiveKit (Avanzado)
### Ventajas:
- ✅ **Sin port forwarding** en router
- ✅ **SSL automático**
- ✅ **Protección DDoS**
- ✅ **IP oculta**
### ⚠️ Limitaciones para WebRTC:
- ❌ **UDP no soportado** directamente
- ⚠️ **Requiere TURN server** para WebRTC
- 🔧 **Solo TCP/HTTP** a través del tunnel
### Configuración (solo si tienes TURN server):
#### Paso 1: Instalar cloudflared
```bash
# Descargar cloudflared
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
```
#### Paso 2: Crear tunnel
```bash
# Login a Cloudflare
cloudflared tunnel login
# Crear tunnel
cloudflared tunnel create livekit-tunnel
# Configurar tunnel
cat > ~/.cloudflared/config.yml << 'EOF'
tunnel: livekit-tunnel
credentials-file: /home/usuario/.cloudflared/livekit-tunnel.json
ingress:
- hostname: livekit.midominio.com
service: http://localhost:7880
- service: http_status:404
EOF
# Crear DNS record
cloudflared tunnel route dns livekit-tunnel livekit.midominio.com
# Ejecutar tunnel
cloudflared tunnel run livekit-tunnel
```
#### Configuración LiveKit (necesita TURN):
```yaml
# livekit-production.yaml
rtc:
# SIN puertos UDP directos - usar TURN
use_external_ip: false
ice_servers:
- urls: ["stun:stun.l.google.com:19302"]
- urls: ["turn:turn.midominio.com:3478"]
username: "usuario"
credential: "password"
```
### ⚠️ **NO RECOMENDADO** para LiveKit porque WebRTC necesita UDP

View File

@ -1,65 +0,0 @@
# CONFIGURACIÓN AVANZADA: ACCESO DESDE INTERNET
## 🌍 Para usuarios externos (más complejo y riesgoso)
### ⚠️ PROBLEMAS de exponer UDP públicamente:
1. **Seguridad**: 10,000 puertos UDP expuestos
2. **Complejidad**: Port forwarding masivo
3. **NAT Traversal**: Problemas con diferentes ISPs
4. **Mantenimiento**: Configuración de router compleja
### Si NECESITAS acceso externo, opciones:
#### Opción A: TURN Server (RECOMENDADO)
```yaml
# livekit-public.yaml
rtc:
use_external_ip: true
external_ip: "TU_IP_PUBLICA"
# Usar TURN para atravesar NAT
ice_servers:
- urls: ["stun:stun.l.google.com:19302"]
- urls: ["turn:tu-turn-server.com:3478"]
username: "usuario"
credential: "password"
# Rango reducido de puertos
port_range_start: 50000
port_range_end: 50100 # Solo 100 puertos
```
#### Opción B: LiveKit Cloud (MÁS RECOMENDADO)
```env
# .env.production
LIVEKIT_URL=wss://tu-proyecto.livekit.cloud
LIVEKIT_API_KEY=cloud-api-key
LIVEKIT_API_SECRET=cloud-secret
# ✅ SIN configuración UDP local
# ✅ Sin port forwarding
# ✅ Infraestructura optimizada
```
#### Opción C: VPN (Para usuarios conocidos)
```bash
# Configurar WireGuard/OpenVPN
# Usuarios se conectan por VPN a tu red local
# Acceso como si fueran locales
# No requiere exponer UDP públicamente
# Acceso seguro y controlado
```
### Port Forwarding (Solo si es absolutamente necesario):
```
⚠️ EN ROUTER:
UDP 50000-60000 → 192.168.1.19:50000-60000
❌ RIESGOS:
- 10,000 puertos UDP expuestos
- Posibles ataques DDoS
- Configuración compleja
- Problemas con CGN/CGNAT de ISPs
```

View File

@ -1,36 +0,0 @@
# CONFIGURACIÓN RECOMENDADA: SOLO RED LOCAL
## 🔒 Para uso en red local ÚNICAMENTE
### Firewall UFW (SOLO red local):
```bash
# Permitir desde red local solamente
sudo ufw allow from 192.168.1.0/24 to any port 50000:60000 proto udp
sudo ufw allow from 192.168.1.0/24 to any port 7880 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 80 proto tcp
# BLOQUEAR acceso externo a UDP
sudo ufw deny 50000:60000/udp
# Verificar que solo red local tenga acceso
sudo ufw status numbered
```
### Router/Modem (NO configurar port forwarding):
```
❌ NO hacer port forwarding de UDP 50000-60000
✅ Solo HTTP (puerto 80) si necesitas acceso web externo
✅ Usar VPN si necesitas acceso remoto
```
### Ventajas:
- ✅ **Seguridad**: UDP no expuesto a internet
- ✅ **Simplicidad**: Sin configuración de router
- ✅ **Rendimiento**: Conexión directa en LAN
- ✅ **Sin NAT**: Sin problemas de traversal
### Casos de uso:
- Oficina local
- Casa/familia
- Reuniones internas
- Desarrollo y testing

View File

@ -1,107 +0,0 @@
# CONFIGURACIÓN DOMINIO PROPIO PARA LIVEKIT
## 🏠 Dominio propio (ej: livekit.midominio.com)
### Opción A: Subdominio de tu dominio existente
#### Paso 1: Configurar DNS
```
Tipo: A
Nombre: livekit
Valor: TU_IP_PUBLICA
TTL: 300
Resultado: livekit.midominio.com → TU_IP_PUBLICA
```
#### Paso 2: Port forwarding en router
```
Puerto 80 → 192.168.1.19:80 # HTTP para Let's Encrypt
Puerto 443 → 192.168.1.19:443 # HTTPS/WSS
Puerto 7880 → 192.168.1.19:7880 # LiveKit API directo
Puerto 50000-50100 (UDP) → 192.168.1.19:50000-50100 # WebRTC
```
#### Paso 3: SSL con Let's Encrypt
```bash
# Instalar certbot
sudo apt update
sudo apt install certbot nginx
# Configurar Nginx básico
sudo tee /etc/nginx/sites-available/livekit << 'EOF'
server {
listen 80;
server_name livekit.midominio.com;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$server_name$request_uri;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/livekit /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl restart nginx
# Generar certificado SSL
sudo certbot --nginx -d livekit.midominio.com
# Resultado: certificados en /etc/letsencrypt/live/livekit.midominio.com/
```
#### Paso 4: Configurar Nginx para LiveKit
```nginx
# /etc/nginx/sites-available/livekit
server {
listen 443 ssl http2;
server_name livekit.midominio.com;
ssl_certificate /etc/letsencrypt/live/livekit.midominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/livekit.midominio.com/privkey.pem;
# WebSocket proxy para LiveKit
location / {
proxy_pass http://localhost:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts para WebRTC
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
server {
listen 80;
server_name livekit.midominio.com;
return 301 https://$server_name$request_uri;
}
```
#### Paso 5: Auto-renovación SSL
```bash
# Agregar a crontab
sudo crontab -e
# Renovar certificados automáticamente
0 12 * * * /usr/bin/certbot renew --quiet && systemctl reload nginx
```
### URLs finales:
- **LiveKit WSS**: `wss://livekit.midominio.com`
- **API HTTPS**: `https://livekit.midominio.com`
### Configurar en OpenVidu Meet:
```env
LIVEKIT_URL=wss://livekit.midominio.com
```

View File

@ -1,72 +0,0 @@
# CONFIGURACIÓN DUCKDNS PARA LIVEKIT
## 🦆 DuckDNS - Dominio gratuito para IP dinámica
### Paso 1: Registrarse en DuckDNS
1. Ir a [duckdns.org](https://www.duckdns.org)
2. Login con Google/GitHub
3. Crear subdominio: `mi-livekit.duckdns.org`
4. Copiar el token
### Paso 2: Script de actualización automática
```bash
# Crear script de actualización
cat > /home/xesar/update-duckdns.sh << 'EOF'
#!/bin/bash
# Actualizar DuckDNS con IP actual
DOMAIN="mi-livekit" # Tu subdominio sin .duckdns.org
TOKEN="tu-token-aqui" # Token de DuckDNS
# Obtener IP pública actual
CURRENT_IP=$(curl -s https://checkip.amazonaws.com)
# Actualizar DuckDNS
RESPONSE=$(curl -s "https://www.duckdns.org/update?domains=$DOMAIN&token=$TOKEN&ip=$CURRENT_IP")
if [ "$RESPONSE" = "OK" ]; then
echo "$(date): DuckDNS actualizado - $DOMAIN.duckdns.org → $CURRENT_IP"
else
echo "$(date): ERROR actualizando DuckDNS: $RESPONSE"
fi
EOF
chmod +x /home/xesar/update-duckdns.sh
```
### Paso 3: Automatizar con cron
```bash
# Editar crontab
crontab -e
# Agregar línea para actualizar cada 5 minutos:
*/5 * * * * /home/xesar/update-duckdns.sh >> /home/xesar/duckdns.log 2>&1
```
### Paso 4: Configurar LiveKit con dominio
```yaml
# livekit-production.yaml
rtc:
external_ip: "mi-livekit.duckdns.org" # Tu dominio DuckDNS
port_range_start: 50000
port_range_end: 50100
```
### Paso 5: Port forwarding en router
```
Regla: LiveKit-API
- Puerto externo: 7880
- Puerto interno: 7880
- IP: 192.168.1.19
- Protocolo: TCP
Regla: LiveKit-WebRTC
- Puerto externo: 50000-50100
- Puerto interno: 50000-50100
- IP: 192.168.1.19
- Protocolo: UDP
```
### URLs finales:
- **LiveKit API**: `ws://mi-livekit.duckdns.org:7880`
- **Con SSL**: `wss://mi-livekit.duckdns.org:443` (después de configurar SSL)

View File

@ -1,67 +0,0 @@
# Multi-stage build para OpenVidu Meet
FROM node:20-alpine AS builder
# Instalar pnpm
RUN npm install -g pnpm
# Copiar archivos del workspace
WORKDIR /app
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
COPY meet-ce/backend/package.json ./meet-ce/backend/
COPY meet-ce/frontend/package.json ./meet-ce/frontend/
COPY meet-ce/frontend/projects/shared-meet-components/package.json ./meet-ce/frontend/projects/shared-meet-components/
# Instalar dependencias
RUN pnpm install --frozen-lockfile
# Copiar código fuente
COPY . .
# Build backend
WORKDIR /app/meet-ce/backend
RUN pnpm run build
# Build frontend
WORKDIR /app/meet-ce/frontend
RUN pnpm run build:prod
# Imagen de producción
FROM node:20-alpine AS production
# Instalar pnpm
RUN npm install -g pnpm
# Crear usuario no-root
RUN addgroup -g 1001 -S nodejs && \
adduser -S openvidu -u 1001
WORKDIR /app
# Copiar package.json y dependencias
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
COPY meet-ce/backend/package.json ./meet-ce/backend/
# Instalar solo dependencias de producción
RUN pnpm install --prod --frozen-lockfile
# Copiar archivos compilados
COPY --from=builder /app/meet-ce/backend/dist ./meet-ce/backend/dist
COPY --from=builder /app/meet-ce/backend/public ./meet-ce/backend/public
# Cambiar propietario
RUN chown -R openvidu:nodejs /app
USER openvidu
# Variables de entorno por defecto
ENV NODE_ENV=production
ENV PORT=6080
ENV MEET_BLOB_STORAGE_MODE=memory
ENV MEET_LOG_LEVEL=info
# Exponer puerto
EXPOSE 6080
# Comando de inicio
WORKDIR /app/meet-ce/backend
CMD ["node", "dist/src/server.js"]

View File

@ -1,52 +0,0 @@
# COMPARACIÓN: OPCIONES PARA EASYPANEL
## 📊 Tabla comparativa
| Opción | Configuración UDP | Costo | Complejidad | Rendimiento | Recomendado |
|--------|------------------|-------|-------------|-------------|-------------|
| **LiveKit Cloud** | ❌ No necesario | $20-100/mes | ⭐ Muy fácil | ⭐⭐⭐ Excelente | ✅ **SÍ** |
| **VPS Híbrido** | ✅ En VPS separado | $10-30/mes | ⭐⭐ Medio | ⭐⭐⭐ Excelente | ⚠️ Si budget limitado |
| **TURN Server** | ✅ 3 puertos en VPS | $5-15/mes | ⭐⭐⭐ Complejo | ⭐⭐ Bueno | ⚠️ Para expertos |
| **EasyPanel Solo** | ❌ Imposible | $0 extra | ❌ No funciona | ❌ No WebRTC | ❌ NO |
## 🏆 RECOMENDACIÓN FINAL
### Para la mayoría de casos: **LiveKit Cloud**
```env
# .env.production para EasyPanel
LIVEKIT_URL=wss://tu-proyecto.livekit.cloud
LIVEKIT_API_KEY=api-key-de-cloud
LIVEKIT_API_SECRET=secret-de-cloud
```
### Ventajas de LiveKit Cloud:
- ✅ **Cero configuración UDP**
- ✅ **Sin VPS adicionales**
- ✅ **Infraestructura global**
- ✅ **Escalabilidad automática**
- ✅ **Soporte oficial**
- ✅ **TURN servers incluidos**
- ✅ **Monitoreo y analytics**
### Costos LiveKit Cloud:
- **Free tier**: 50GB/mes gratis
- **Starter**: $20/mes - 500GB
- **Pro**: $99/mes - 2TB + features
### Setup LiveKit Cloud:
1. **Registro**: https://cloud.livekit.io
2. **Crear proyecto**
3. **Copiar credenciales**
4. **Configurar en EasyPanel**
5. **Deploy**
## 🎯 PASOS SIGUIENTE PARA TI
¿Qué opción prefieres?
1. **LiveKit Cloud** (fácil, costo medio)
2. **VPS Híbrido** (control total, setup complejo)
3. **TURN Server** (experto, costo bajo)
Te ayudo a configurar la que elijas.

View File

@ -1,113 +0,0 @@
# CONFIGURACIÓN EASYPANEL - OpenVidu Meet
# ========================================
## 📋 CONFIGURACIÓN DEL PROYECTO
### 1. Crear Proyecto en EasyPanel
- Tipo: Docker Compose o Docker Build
- Repositorio: Tu repo con estos archivos
- Branch: main
### 2. Variables de Entorno Requeridas
```env
# Básicas
NODE_ENV=production
MEET_LOG_LEVEL=info
MEET_BLOB_STORAGE_MODE=memory
# Admin (CAMBIAR)
ADMIN_PASSWORD=tu-password-seguro-aqui
# LiveKit (ajustar según tu setup)
LIVEKIT_URL=wss://tu-livekit-domain.com
LIVEKIT_API_KEY=tu-api-key
LIVEKIT_API_SECRET=tu-secret-32-caracteres-minimo
# Proxy
TRUST_PROXY=true
SERVER_CORS_ORIGIN=*
USE_HTTPS=true
```
### 3. Configuración de Puertos
- **Opción A (con Nginx)**: Puerto 80
- **Opción B (directo)**: Puerto 6080
### 4. Configuración de Dominio
- Agregar tu dominio en EasyPanel
- Habilitar SSL automático
- Configurar redirects HTTP → HTTPS
## 🐳 OPCIONES DE DEPLOY
### Opción A: Con Nginx Proxy (Recomendado)
```yaml
# Usar docker-compose.yml completo
# Puerto expuesto: 80/443
# Incluye rate limiting y optimizaciones
```
### Opción B: Solo Backend
```yaml
# Solo el servicio openvidu-meet del compose
# Puerto expuesto: 6080
# EasyPanel maneja el proxy
```
## 🔧 CONFIGURACIONES ADICIONALES
### LiveKit Setup
1. Desplegar LiveKit en servidor separado
2. Configurar LIVEKIT_URL con dominio público
3. Generar API keys seguros
### Redis (Opcional)
- Usar servicio Redis de EasyPanel
- O mantener storage en memoria para simplicidad
### SSL/TLS
- EasyPanel maneja certificados automáticamente
- Configurar HTTPS en variables de entorno
## 🚨 CONSIDERACIONES DE SEGURIDAD
1. **Cambiar credenciales por defecto**
2. **Usar secrets seguros para LiveKit**
3. **Configurar CORS apropiadamente**
4. **Habilitar rate limiting**
5. **Usar HTTPS únicamente**
## 📊 MONITOREO
### Health Checks
- `/nginx-health` - Estado del proxy
- `/api/health` - Estado del backend
- Logs en EasyPanel dashboard
### Métricas
- CPU/Memory usage
- Response times
- Error rates
## 🔄 ACTUALIZACIONES
1. Push cambios al repo
2. EasyPanel rebuilds automáticamente
3. Zero-downtime deployment
## 🐛 TROUBLESHOOTING
### Backend no arranca
- Verificar variables de entorno
- Revisar logs en EasyPanel
- Verificar puertos
### Error de proxy
- Verificar nginx.conf
- Revisar headers
- Verificar upstreams
### LiveKit no conecta
- Verificar LIVEKIT_URL
- Verificar API keys
- Verificar connectivity

View File

@ -1,164 +0,0 @@
# 🚀 **DEPLOYMENT EN EASYPANEL - SIMPLIFICADO**
## 📋 **RESUMEN DE CONFIGURACIÓN**
✅ **EasyPanel maneja automáticamente:**
- SSL/TLS con certificados gratuitos
- Subdominios (ej: `tu-app.easypanel.host`)
- Proxy reverso con Traefik
- HTTPS redirect
✅ **Tu aplicación expone:**
- Solo puerto 80 (HTTP)
- Nginx como proxy interno
- OpenVidu Meet backend
---
## 🔧 **PASOS DE DEPLOYMENT**
### **1. Preparar archivos**
```bash
# Los archivos ya están listos:
# ✅ Dockerfile (optimizado)
# ✅ docker-compose.yml (puerto 80 solamente)
# ✅ nginx.conf (sin SSL - solo HTTP)
# ✅ .env.production (variables de entorno)
```
### **2. Subir a repositorio Git**
```bash
git add Dockerfile docker-compose.yml nginx.conf .env.production
git commit -m "Add EasyPanel deployment config"
git push
```
### **3. Crear proyecto en EasyPanel**
#### **Opción A: Docker Compose (Recomendado)**
1. **Nuevo Proyecto** → **Deploy from Git**
2. **Conectar repositorio**
3. **Tipo:** Docker Compose
4. **Archivo:** `docker-compose.yml`
5. **Puerto expuesto:** `80`
#### **Opción B: Dockerfile simple**
1. **Nuevo Proyecto** → **Deploy from Git**
2. **Tipo:** Dockerfile
3. **Puerto:** `6080`
4. **Health Check:** `/health`
### **4. Variables de entorno en EasyPanel**
En el dashboard de EasyPanel, configurar:
```env
# ADMIN (¡CAMBIAR!)
ADMIN_PASSWORD=mi-password-super-seguro
# LIVEKIT (configurar según tu setup)
LIVEKIT_URL=wss://tu-livekit-domain.com
LIVEKIT_API_KEY=tu-api-key
LIVEKIT_API_SECRET=tu-secret-de-32-caracteres
# REDIS (opcional)
REDIS_HOST=tu-redis-host
REDIS_PASSWORD=tu-redis-password
```
### **5. Deploy**
- Hacer clic en **Deploy**
- EasyPanel construirá automáticamente
- Generará subdominio (ej: `openvidu-meet.easypanel.host`)
- Aplicará SSL automáticamente
---
## 🌐 **RESULTADO FINAL**
```
https://tu-app.easypanel.host
├── EasyPanel Traefik Proxy (SSL/HTTPS)
└── Tu Container (puerto 80)
├── Nginx (proxy interno)
└── OpenVidu Meet Backend (:6080)
```
### **URLs disponibles:**
- **Aplicación:** `https://tu-app.easypanel.host`
- **Admin Login:** `https://tu-app.easypanel.host/admin`
- **API:** `https://tu-app.easypanel.host/api/`
- **Health Check:** `https://tu-app.easypanel.host/health`
---
## 🔧 **CONFIGURACIÓN LIVEKIT**
Para que funcione completamente, necesitas **LiveKit server** separado:
### **Opción 1: LiveKit en EasyPanel (otro proyecto)**
```yaml
# livekit.yaml para EasyPanel
port: 7880
redis:
address: tu-redis:6379
password: tu-password
```
### **Opción 2: LiveKit Cloud**
- Registrarse en [LiveKit Cloud](https://cloud.livekit.io)
- Copiar `LIVEKIT_URL`, `API_KEY`, `API_SECRET`
- Configurar en variables de entorno
---
## 🔐 **SEGURIDAD**
### **Cambiar credenciales por defecto:**
```env
ADMIN_PASSWORD=un-password-muy-seguro
LIVEKIT_API_SECRET=secret-de-al-menos-32-caracteres
```
### **Headers de seguridad incluidos:**
- Rate limiting (API: 10req/s, Login: 1req/s)
- X-Frame-Options
- X-Content-Type-Options
- X-XSS-Protection
---
## 🚨 **TROUBLESHOOTING**
### **El container no inicia:**
```bash
# Ver logs en EasyPanel dashboard
# O conectar por SSH:
docker logs container-name
```
### **502 Bad Gateway:**
- Verificar que el backend responde en puerto 6080
- Health check: `curl localhost:6080/health`
### **WebSocket no funciona:**
- Verificar configuración de LiveKit
- Headers de WebSocket están configurados en nginx
### **Admin login no funciona:**
- Verificar variable `ADMIN_PASSWORD`
- Limpiar datos Redis si está configurado
---
## ✅ **CHECKLIST FINAL**
- [ ] Repository con archivos de deployment subido
- [ ] Proyecto creado en EasyPanel
- [ ] Variables de entorno configuradas
- [ ] Password admin cambiado
- [ ] LiveKit configurado (separado)
- [ ] SSL funcionando automáticamente
- [ ] Admin login funcional en `/admin`
**¡Ya tienes OpenVidu Meet funcionando en producción con EasyPanel!** 🎉

View File

@ -1,104 +0,0 @@
# SOLUCIÓN: TURN SERVER PARA EASYPANEL
## 🔄 TURN Server como alternativa para NAT traversal
### ¿Qué es TURN?
TURN (Traversal Using Relays around NAT) permite que WebRTC funcione sin exponer miles de puertos UDP.
## 🏗️ ARQUITECTURA CON TURN
```
Cliente → Internet → TURN Server → EasyPanel
(3 puertos) (sin UDP)
Vs. directo:
Cliente → Internet → EasyPanel
(10,000 UDP) ❌ No posible
```
## 📋 IMPLEMENTACIÓN
### 1. TURN Server en VPS separado
```bash
# Instalar Coturn en VPS
apt-get update
apt-get install coturn
# /etc/turnserver.conf
listening-port=3478
tls-listening-port=5349
external-ip=IP_PUBLICA_VPS
realm=turn.tu-dominio.com
lt-cred-mech
user=usuario:password123
verbose
```
### 2. Firewall VPS (Solo 3 puertos)
```bash
# Solo estos 3 puertos para TURN
ufw allow 3478/tcp # TURN TCP
ufw allow 3478/udp # TURN UDP
ufw allow 5349/tcp # TURN over TLS
ufw enable
```
### 3. LiveKit en EasyPanel con TURN
```yaml
# livekit.yaml para EasyPanel
port: 7880
keys:
devkey: tu-secret-32-chars
# SIN puertos UDP locales - usar TURN
rtc:
# NO port_range - usa TURN
use_external_ip: false
# Configurar TURN servers
ice_servers:
- urls: ["stun:stun.l.google.com:19302"]
- urls: ["turn:turn.tu-dominio.com:3478"]
username: "usuario"
credential: "password123"
- urls: ["turns:turn.tu-dominio.com:5349"]
username: "usuario"
credential: "password123"
```
### 4. Variables EasyPanel
```env
# Solo TCP - SIN UDP
LIVEKIT_URL=wss://tu-app.easypanel.host/livekit
LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=tu-secret-32-chars
```
### 5. Nginx en EasyPanel para proxy LiveKit
```nginx
# nginx.conf - agregar ruta para LiveKit
location /livekit {
proxy_pass http://openvidu-meet:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
```
## 💰 COSTOS
- **TURN VPS**: $5-10/mes (pequeño VPS)
- **EasyPanel**: Tu plan actual
- **Total**: +$5-10/mes vs LiveKit Cloud
## ✅ VENTAJAS
- ✅ Solo 3 puertos UDP en VPS externo
- ✅ EasyPanel sin UDP
- ✅ NAT traversal garantizado
- ✅ Menor costo que LiveKit Cloud
## ❌ DESVENTAJAS
- ❌ Configuración más compleja
- ❌ VPS adicional para TURN
- ❌ Latencia adicional (relay)
- ❌ Ancho de banda TURN server

View File

@ -1,29 +0,0 @@
# LIMITACIONES DE EASYPANEL PARA UDP
## ❌ Por qué EasyPanel NO puede exponer UDP:
### Arquitectura de EasyPanel:
```
Internet → Traefik (HTTP/HTTPS Proxy) → Tu Container
Solo maneja TCP/HTTP/HTTPS
NO puede proxy UDP
```
### Limitaciones técnicas:
1. **Traefik**: Solo HTTP/HTTPS reverse proxy
2. **Docker networking**: Limitado a puertos TCP expuestos
3. **UI de EasyPanel**: Solo configuración HTTP
4. **Load balancing**: Diseñado para web apps, no media streaming
### Puertos disponibles en EasyPanel:
- ✅ 80 (HTTP)
- ✅ 443 (HTTPS)
- ✅ Puertos TCP custom
- ❌ Puertos UDP (NO DISPONIBLE)
## ⚠️ Problemas si intentas exponer UDP:
- EasyPanel UI no tiene opción para UDP
- Traefik no puede hacer proxy de UDP
- Docker compose limitado a TCP en EasyPanel
- No hay configuración de port ranges UDP

View File

@ -1,129 +0,0 @@
# SOLUCIÓN: LIVEKIT EN VPS SEPARADO + EASYPANEL
## 🏗️ ARQUITECTURA HÍBRIDA
```
┌─ EasyPanel ────────────────┐ ┌─ VPS Separado ─────────┐
│ │ │ │
│ OpenVidu Meet Backend ──────────→ LiveKit Server │
│ (HTTP/HTTPS only) │ │ (UDP 50000-60000) │
│ │ │ │
└────────────────────────────┘ └────────────────────────┘
↑ ↑
Traefik/SSL Firewall/UDP abierto
```
## 📋 CONFIGURACIÓN PASO A PASO
### 1. EasyPanel (Solo OpenVidu Meet Backend)
```yaml
# docker-compose.yml para EasyPanel
version: '3.8'
services:
openvidu-meet:
build: .
environment:
# LiveKit en VPS externo
LIVEKIT_URL: wss://livekit.tu-vps.com:7880
LIVEKIT_API_KEY: devkey
LIVEKIT_API_SECRET: tu-secret-32-chars
ports:
- "80:6080" # Solo HTTP - EasyPanel maneja SSL
```
### 2. VPS Separado (Solo LiveKit + Redis)
```yaml
# docker-compose.yml en VPS
version: '3.8'
services:
livekit:
image: livekit/livekit-server:latest
ports:
- "7880:7880" # API/WebSocket
- "50000-60000:50000-60000/udp" # WebRTC
volumes:
- ./livekit.yaml:/livekit.yaml
command: --config /livekit.yaml
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --requirepass redispassword
```
### 3. Configuración LiveKit en VPS
```yaml
# livekit.yaml en VPS
port: 7880
bind_addresses: ["0.0.0.0"]
keys:
devkey: tu-secret-de-32-caracteres-minimo
redis:
address: "localhost:6379"
password: "redispassword"
rtc:
port_range_start: 50000
port_range_end: 60000
use_external_ip: true
external_ip: "IP_PUBLICA_DEL_VPS"
ice_servers:
- urls: ["stun:stun.l.google.com:19302"]
```
### 4. Firewall en VPS
```bash
# Configurar firewall en VPS
ufw allow 7880/tcp # LiveKit API
ufw allow 50000:60000/udp # WebRTC UDP
ufw allow 6379/tcp # Redis (si acceso externo)
ufw enable
```
### 5. SSL para LiveKit (Nginx en VPS)
```nginx
# /etc/nginx/sites-available/livekit
server {
listen 443 ssl;
server_name livekit.tu-vps.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
```
## 💰 COSTOS ESTIMADOS
### VPS para LiveKit:
- **Básico**: $5-10/mes (2GB RAM, 1 CPU)
- **Medio**: $15-25/mes (4GB RAM, 2 CPU)
- **Alto**: $30-50/mes (8GB RAM, 4 CPU)
### Proveedores recomendados:
- DigitalOcean
- Linode
- Hetzner
- Vultr
## ✅ VENTAJAS
- ✅ EasyPanel para web app (fácil)
- ✅ VPS dedicado para WebRTC (potencia)
- ✅ Escalabilidad independiente
- ✅ Control total sobre LiveKit
## ❌ DESVENTAJAS
- ❌ Costo adicional VPS
- ❌ Más complejidad de setup
- ❌ Mantenimiento de dos servicios

View File

@ -1,180 +0,0 @@
# SERVIDOR LIVEKIT SELF-HOSTING DEDICADO
## 🖥️ Setup en servidor dedicado (192.168.1.19)
### Docker Compose para LiveKit Server:
```yaml
# docker-compose-livekit-server.yml
version: '3.8'
services:
# LiveKit Server Principal
livekit-server:
image: livekit/livekit-server:latest
container_name: livekit-production
restart: unless-stopped
ports:
# API/WebSocket (EXPONER PÚBLICAMENTE)
- "7880:7880"
# Rango UDP para WebRTC (EXPONER PÚBLICAMENTE)
- "50000-50100:50000-50100/udp" # 100 puertos para ~10 usuarios concurrentes
volumes:
- ./livekit-production.yaml:/livekit.yaml:ro
- ./logs:/app/logs
command: --config /livekit.yaml
environment:
- LIVEKIT_CONFIG=/livekit.yaml
networks:
- livekit-network
depends_on:
- redis
# Redis para LiveKit
redis:
image: redis:7-alpine
container_name: livekit-redis
restart: unless-stopped
ports:
- "6379:6379"
command: redis-server --requirepass ${REDIS_PASSWORD:-livekitredis123}
volumes:
- redis_data:/data
networks:
- livekit-network
# Nginx SSL Termination (para HTTPS/WSS)
nginx-livekit:
image: nginx:alpine
container_name: livekit-nginx
restart: unless-stopped
ports:
- "443:443" # HTTPS/WSS (EXPONER PÚBLICAMENTE)
- "80:80" # HTTP redirect
volumes:
- ./nginx-livekit.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro # Certificados SSL
depends_on:
- livekit-server
networks:
- livekit-network
volumes:
redis_data:
networks:
livekit-network:
driver: bridge
```
### Configuración LiveKit Production:
```yaml
# livekit-production.yaml
port: 7880
bind_addresses: ["0.0.0.0"]
# API Keys seguros
keys:
production-key: tu-super-secret-de-32-caracteres-o-mas
# Redis para scaling y persistence
redis:
address: "redis:6379"
password: "livekitredis123"
db: 0
# RTC Configuration para acceso público
rtc:
# Puertos UDP (coincidir con docker-compose)
port_range_start: 50000
port_range_end: 50100
# IP pública/externa (tu IP pública o dominio)
use_external_ip: true
external_ip: "TU_IP_PUBLICA_O_DOMINIO" # ej: "mi-casa.duckdns.org"
# STUN servers para NAT traversal
ice_servers:
- urls: ["stun:stun.l.google.com:19302"]
- urls: ["stun:stun1.l.google.com:19302"]
# Room settings para producción
room:
auto_create: true
max_participants: 50
empty_timeout: 600 # 10 minutos
# Security
webhook:
# Opcional: webhook para eventos
api_key: "tu-webhook-key"
# Logging
log_level: info
log_format: json
# Enable egress (grabaciones)
# Automático con Redis
```
### Nginx SSL para LiveKit:
```nginx
# nginx-livekit.conf
events {
worker_connections 1024;
}
http {
# Redirect HTTP to HTTPS
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
# HTTPS/WSS Server
server {
listen 443 ssl http2;
server_name _;
# SSL Configuration
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# WebSocket support para LiveKit
location / {
proxy_pass http://livekit-server:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts para WebRTC
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
}
```
## 🔥 Firewall en servidor LiveKit:
```bash
# UFW rules para exposición pública segura
sudo ufw allow 80/tcp comment "HTTP redirect"
sudo ufw allow 443/tcp comment "HTTPS/WSS LiveKit"
sudo ufw allow 7880/tcp comment "LiveKit API directo"
sudo ufw allow 50000:50100/udp comment "WebRTC UDP range"
# Opcional: limitar SSH a red local solamente
sudo ufw allow from 192.168.1.0/24 to any port 22
sudo ufw enable
sudo ufw status numbered
```

View File

@ -1,40 +0,0 @@
# CONFIGURACIÓN TURN PARA LIVEKIT
## 🔧 Si necesitas TURN server para LiveKit detrás de firewall:
### 1. Configurar Coturn (TURN server)
```bash
# Instalar coturn
apt-get install coturn
# /etc/turnserver.conf
listening-port=3478
tls-listening-port=5349
external-ip=TU_IP_PUBLICA
realm=tu-dominio.com
lt-cred-mech
user=usuario:password
```
### 2. Configurar LiveKit con TURN
```yaml
# livekit.yaml
rtc:
port_range_start: 50000
port_range_end: 60000
ice_servers:
- urls:
- "stun:stun.l.google.com:19302"
- "turn:tu-turn-server.com:3478"
username: "usuario"
credential: "password"
```
### 3. Firewall para TURN
```bash
# Puertos necesarios
ufw allow 3478/tcp # TURN TCP
ufw allow 3478/udp # TURN UDP
ufw allow 5349/tcp # TURN TLS
ufw allow 50000:60000/udp # Media streams
```

View File

@ -8,8 +8,8 @@ OpenVidu Meet is a fully featured video conferencing application built with Angu
2. [Prerequisites](#prerequisites)
3. [Getting Started](#getting-started)
4. [Development](#development)
- [Development Mode](#development-mode)
- [Manual Development Setup](#manual-development-setup)
- [Development Mode](#development-mode)
- [Manual Development Setup](#manual-development-setup)
5. [Building](#building)
6. [Testing](#testing)
7. [Documentation](#documentation)
@ -26,12 +26,12 @@ The OpenVidu Meet application is a monorepo managed with **pnpm workspaces** and
### Core Components
- **Frontend** (`frontend/`): Angular 20 application providing the user interface
- **shared-meet-components**: Reusable Angular library with shared components for administration and preferences
- Integrates [openvidu-components-angular](https://github.com/OpenVidu/openvidu/tree/master/openvidu-components-angular) for core video conferencing functionality
- **shared-meet-components**: Reusable Angular library with shared components for administration and preferences
- Integrates [openvidu-components-angular](https://github.com/OpenVidu/openvidu/tree/master/openvidu-components-angular) for core video conferencing functionality
- **Backend** (`backend/`): Node.js/TypeScript REST API server
- Manages rooms, participants, recordings, and authentication
- Serves the compiled frontend in production
- Manages rooms, participants, recordings, and authentication
- Serves the compiled frontend in production
- **Typings** (`typings/`): Shared TypeScript type definitions used across frontend and backend
@ -46,10 +46,9 @@ Before starting, ensure you have the following installed:
- **Node.js**: Version 22 or higher
- **pnpm**: Package manager (will be installed automatically by meet.sh if missing)
- **LiveKit**: For local testing (optional)
```bash
curl -sSL https://get.livekit.io/cli | bash
```
```bash
curl -sSL https://get.livekit.io/cli | bash
```
## Getting Started
@ -82,7 +81,7 @@ cd openvidu-meet
Then, the application will be available at [http://localhost:6080](http://localhost:6080).
> **Note:** Livereload is also available at [http://localhost:5080](http://localhost:5080).
> **Note:** Livereload is also available at [http://localhost:6081](http://localhost:6081).
## Development
@ -95,6 +94,7 @@ The recommended way to develop is using the integrated development mode that wat
```
This command starts concurrent watchers for:
- **openvidu-components-angular**: Core Angular components library
- **Typings**: Shared type definitions with automatic sync
- **Backend**: Node.js server with nodemon auto-restart
@ -103,6 +103,7 @@ This command starts concurrent watchers for:
> [!NOTE]
> The backend uses `backend/.env.development` for environment variables during development. Configure your LiveKit credentials there:
>
> ```env
> LIVEKIT_URL=ws://localhost:7880
> LIVEKIT_API_KEY=your-api-key
@ -170,6 +171,7 @@ The `meet.sh` script supports flags to optimize CI/CD pipelines:
```
**Available flags:**
- `--skip-install`: Skip dependency installation
- `--skip-build`: Skip build steps
- `--skip-typings`: Skip typings build (use when already built)
@ -225,8 +227,9 @@ The test app will be available at [http://localhost:5080](http://localhost:5080)
```
Documentation files will be generated in:
- **Webcomponent**: `docs/webcomponent-*.md` (events, commands, attributes)
- **REST API**: `backend/public/openapi/public.html`
- **REST API**: `meet-ce/backend/public/openapi/public.html`
If you specify an output directory, the documentation will be copied there.
@ -289,35 +292,41 @@ openvidu-meet/
│ ├── src/
│ │ ├── api-key.ts
│ │ ├── auth-config.ts
│ │ ├── participant.ts
│ │ ├── event.model.ts
│ │ ├── room.ts
│ │ └── ...
│ └── package.json
├── frontend/ # Angular frontend application
├── frontend/ # Angular frontend application
│ ├── src/ # Main application source
│ ├── projects/
│ │ └── shared-meet-components/ # Reusable Angular library
│ └── webcomponent/ # Web component build
├── backend/ # Node.js/Express backend
├── backend/ # Node.js/Express backend
│ ├── src/
│ │ ├── config/ # Configuration files
│ │ ├── controllers/ # REST API controllers
│ │ ├── services/ # Business logic
│ │ ├── helpers/ # Helper functions
│ │ ├── middleware/ # Express middleware
│ │ ├── migrations/ # Database migration scripts
│ │ ├── models/ # Domain models
│ │ ├── repositories/ # Database interaction
│ │ ├── routes/ # API route definitions
│ │ ├── services/ # Business logic
│ │ ├── utils/ # Utility functions
│ │ └── environment.ts # Environment configuration
│ ├── openapi/ # OpenAPI specifications
│ └── public/ # Static files (includes built frontend)
├── testapp/ # Testing application
├── testapp/ # Testing application
│ ├── src/
│ └── public/
├── docker/ # Docker build files
├── docker/ # Docker build files
│ └── create_image.sh
├── docs/ # Generated documentation
├── scripts/ # Build and utility scripts
├── docs/ # Generated documentation
├── scripts/ # Build and utility scripts
└── openvidu-meet-pro/ # Professional Edition (separate license)
```
@ -412,6 +421,7 @@ Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for detai
- [OpenVidu Website](https://openvidu.io/)
- [OpenVidu Meet](https://openvidu.io/latest/meet/)
---
For questions and support, visit our [community forum](https://openvidu.discourse.group/).

View File

@ -1,103 +0,0 @@
# CONFIGURACIÓN ROUTER - PORT FORWARDING PARA LIVEKIT
## 🌐 Port Forwarding necesario en tu Router
### Puertos a exponer públicamente:
| Servicio | Puerto | Protocolo | IP Interna | Descripción |
|----------|---------|-----------|------------|-------------|
| **HTTP** | 80 | TCP | 192.168.1.19 | Redirect a HTTPS |
| **HTTPS/WSS** | 443 | TCP | 192.168.1.19 | LiveKit WebSocket Secure |
| **LiveKit API** | 7880 | TCP | 192.168.1.19 | API directa (opcional) |
| **WebRTC Media** | 50000-50100 | UDP | 192.168.1.19 | Streams de audio/video |
### Configuración típica router:
```
Regla 1: LiveKit-HTTPS
- Servicio: HTTPS/Custom
- Puerto externo: 443
- Puerto interno: 443
- IP interna: 192.168.1.19
- Protocolo: TCP
- Estado: Habilitado
Regla 2: LiveKit-HTTP
- Servicio: HTTP
- Puerto externo: 80
- Puerto interno: 80
- IP interna: 192.168.1.19
- Protocolo: TCP
- Estado: Habilitado
Regla 3: LiveKit-WebRTC
- Servicio: Custom
- Puerto externo: 50000-50100
- Puerto interno: 50000-50100
- IP interna: 192.168.1.19
- Protocolo: UDP
- Estado: Habilitado
```
## 🏠 IP Dinámica - Solución con DuckDNS
### Si tu IP pública cambia (típico en casa):
```bash
# 1. Crear cuenta en DuckDNS.org
# 2. Crear subdominio: mi-livekit.duckdns.org
# 3. Script de actualización automática
# /home/usuario/update-duckdns.sh
#!/bin/bash
echo url="https://www.duckdns.org/update?domains=mi-livekit&token=TU_TOKEN&ip=" | curl -k -o ~/duckdns.log -K -
# Crontab para actualizar cada 5 minutos
# crontab -e
*/5 * * * * /home/usuario/update-duckdns.sh >/dev/null 2>&1
```
### Configurar dominio en LiveKit:
```yaml
# livekit-production.yaml
rtc:
external_ip: "mi-livekit.duckdns.org" # En lugar de IP
```
## 🔒 Certificado SSL automático con Let's Encrypt
```bash
# Instalar certbot
sudo apt install certbot
# Generar certificado para tu dominio
sudo certbot certonly --standalone -d mi-livekit.duckdns.org
# Copiar certificados para Docker
sudo cp /etc/letsencrypt/live/mi-livekit.duckdns.org/fullchain.pem ./ssl/cert.pem
sudo cp /etc/letsencrypt/live/mi-livekit.duckdns.org/privkey.pem ./ssl/key.pem
sudo chown $USER:$USER ./ssl/*.pem
# Auto-renovación (crontab)
0 12 * * * /usr/bin/certbot renew --quiet && docker-compose restart nginx-livekit
```
## 📊 Verificación de conectividad
### Tests externos:
```bash
# Test puertos desde internet
nmap -p 80,443,7880 mi-livekit.duckdns.org
nmap -sU -p 50000-50010 mi-livekit.duckdns.org
# Test WebSocket
wscat -c wss://mi-livekit.duckdns.org
# Test HTTPS
curl -I https://mi-livekit.duckdns.org
```
### URLs finales:
- **LiveKit WSS**: `wss://mi-livekit.duckdns.org`
- **API HTTP**: `https://mi-livekit.duckdns.org`
- **Monitoreo**: `https://mi-livekit.duckdns.org/debug`

View File

@ -1,106 +0,0 @@
# CONFIGURACIÓN MANUAL DE PUERTOS UDP PARA LIVEKIT
## 🔥 FIREWALL UBUNTU/DEBIAN (UFW)
```bash
# Puertos TCP
sudo ufw allow 80/tcp comment "HTTP"
sudo ufw allow 6080/tcp comment "OpenVidu Meet"
sudo ufw allow 6379/tcp comment "Redis"
sudo ufw allow 7880/tcp comment "LiveKit API"
# Puertos UDP para WebRTC
sudo ufw allow 50000:60000/udp comment "LiveKit WebRTC"
# Verificar
sudo ufw status numbered
```
## 🔥 FIREWALL CENTOS/RHEL (firewalld)
```bash
# Puertos TCP
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=6080/tcp
sudo firewall-cmd --permanent --add-port=6379/tcp
sudo firewall-cmd --permanent --add-port=7880/tcp
# Puertos UDP
sudo firewall-cmd --permanent --add-port=50000-60000/udp
# Aplicar
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports
```
## 🖥️ ROUTER/MODEM (Para acceso externo)
Si quieres acceso desde internet:
### Port Forwarding necesario:
- **TCP 80** → Tu servidor (OpenVidu Meet)
- **TCP 7880** → Tu servidor (LiveKit API)
- **UDP 50000-60000** → Tu servidor (WebRTC media)
### Configuración típica router:
```
Servicio: OpenVidu-HTTP
Puerto externo: 80
Puerto interno: 80
IP interna: 192.168.1.19
Protocolo: TCP
Servicio: LiveKit-API
Puerto externo: 7880
Puerto interno: 7880
IP interna: 192.168.1.19
Protocolo: TCP
Servicio: WebRTC-Media
Puerto externo: 50000-60000
Puerto interno: 50000-60000
IP interna: 192.168.1.19
Protocolo: UDP
```
## 🔍 VERIFICACIÓN DE PUERTOS
### Verificar puertos abiertos:
```bash
# Ver todos los puertos TCP/UDP en uso
sudo ss -tulnp
# Específicos de LiveKit
sudo ss -tulnp | grep -E "(7880|50000|60000)"
# Verificar desde otro dispositivo
nmap -p 7880,50000-50010 192.168.1.19
```
### Test de conectividad:
```bash
# Test TCP (LiveKit API)
curl http://192.168.1.19:7880
# Test WebSocket
wscat -c ws://192.168.1.19:7880
# Test UDP (requiere herramientas específicas)
nc -u 192.168.1.19 50000
```
## ⚠️ CONSIDERACIONES IMPORTANTES
### Para red local:
- ✅ Solo configurar firewall del servidor
- ✅ Usar IP local (192.168.x.x)
- ✅ No necesita port forwarding
### Para acceso externo:
- ⚠️ Configurar port forwarding en router
- ⚠️ Usar IP pública o dominio
- ⚠️ Configurar HTTPS para LiveKit
- ⚠️ Considerar seguridad (VPN, etc.)
### Rango de puertos UDP:
- **Mínimo:** 100 puertos (ej: 50000-50100)
- **Recomendado:** 1000 puertos (50000-51000)
- **Máximo configurado:** 10000 puertos (50000-60000)
- **Cálculo:** ~10 puertos por participante simultáneo

View File

@ -1,190 +0,0 @@
#!/bin/bash
# Script para configurar dominio automáticamente para LiveKit
set -e
# Colores
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}🌐 Configurador de Dominio para LiveKit${NC}"
echo ""
# Detectar IP pública
echo "🔍 Detectando IP pública..."
PUBLIC_IP=$(curl -s https://checkip.amazonaws.com || curl -s https://ipinfo.io/ip || echo "No detectada")
LOCAL_IP=$(hostname -I | awk '{print $1}')
echo -e "${BLUE}📊 Información de red:${NC}"
echo " IP Local: $LOCAL_IP"
echo " IP Pública: $PUBLIC_IP"
echo ""
# Opciones de dominio
echo "¿Qué tipo de dominio quieres configurar?"
echo "1) DuckDNS (gratuito, IP dinámica)"
echo "2) Dominio propio + Let's Encrypt"
echo "3) Solo IP pública (sin dominio)"
echo ""
read -p "Selecciona opción (1-3): " DOMAIN_OPTION
case $DOMAIN_OPTION in
1)
echo -e "${GREEN}🦆 Configurando DuckDNS${NC}"
read -p "Subdominio DuckDNS (sin .duckdns.org): " DUCKDNS_SUBDOMAIN
read -p "Token DuckDNS: " DUCKDNS_TOKEN
DOMAIN="$DUCKDNS_SUBDOMAIN.duckdns.org"
# Crear script de actualización
cat > update-duckdns.sh << EOF
#!/bin/bash
CURRENT_IP=\$(curl -s https://checkip.amazonaws.com)
RESPONSE=\$(curl -s "https://www.duckdns.org/update?domains=$DUCKDNS_SUBDOMAIN&token=$DUCKDNS_TOKEN&ip=\$CURRENT_IP")
if [ "\$RESPONSE" = "OK" ]; then
echo "\$(date): DuckDNS actualizado - $DOMAIN → \$CURRENT_IP"
else
echo "\$(date): ERROR: \$RESPONSE"
fi
EOF
chmod +x update-duckdns.sh
# Actualizar inmediatamente
./update-duckdns.sh
# Configurar cron
(crontab -l 2>/dev/null; echo "*/5 * * * * $(pwd)/update-duckdns.sh >> $(pwd)/duckdns.log 2>&1") | crontab -
echo -e "${GREEN}✅ DuckDNS configurado: $DOMAIN${NC}"
LIVEKIT_URL="ws://$DOMAIN:7880"
;;
2)
echo -e "${GREEN}🏠 Configurando dominio propio${NC}"
read -p "Dominio completo (ej: livekit.midominio.com): " CUSTOM_DOMAIN
DOMAIN="$CUSTOM_DOMAIN"
echo -e "${YELLOW}📋 Pasos manuales necesarios:${NC}"
echo "1. Configurar DNS A record:"
echo " $DOMAIN$PUBLIC_IP"
echo ""
echo "2. Port forwarding en router:"
echo " TCP 80,443,7880 → $LOCAL_IP"
echo " UDP 50000-50100 → $LOCAL_IP"
echo ""
read -p "¿Continuar con configuración SSL automática? (y/N): " SSL_SETUP
if [[ $SSL_SETUP =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}🔧 Configurando Nginx + SSL...${NC}"
# Instalar dependencias
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
# Configurar Nginx básico
sudo tee /etc/nginx/sites-available/livekit << EOF
server {
listen 80;
server_name $DOMAIN;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://\$server_name\$request_uri;
}
}
EOF
sudo ln -sf /etc/nginx/sites-available/livekit /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl restart nginx
# Generar certificado
sudo certbot --nginx -d $DOMAIN --non-interactive --agree-tos --email admin@$DOMAIN
echo -e "${GREEN}✅ SSL configurado para $DOMAIN${NC}"
fi
LIVEKIT_URL="wss://$DOMAIN"
;;
3)
echo -e "${YELLOW}📡 Usando IP pública directa${NC}"
DOMAIN="$PUBLIC_IP"
LIVEKIT_URL="ws://$PUBLIC_IP:7880"
;;
*)
echo -e "${RED}❌ Opción inválida${NC}"
exit 1
;;
esac
# Actualizar configuración LiveKit
echo -e "${YELLOW}🔧 Actualizando configuración LiveKit...${NC}"
# Actualizar livekit.yaml existente o crear nuevo
if [ -f "livekit-production.yaml" ]; then
sed -i "s/external_ip: .*/external_ip: \"$DOMAIN\"/" livekit-production.yaml
echo -e "${GREEN}✅ livekit-production.yaml actualizado${NC}"
elif [ -f "livekit.yaml" ]; then
sed -i "s/external_ip: .*/external_ip: \"$DOMAIN\"/" livekit.yaml
echo -e "${GREEN}✅ livekit.yaml actualizado${NC}"
else
echo -e "${YELLOW}⚠️ No se encontró archivo de configuración LiveKit${NC}"
fi
# Actualizar variables para OpenVidu Meet
cat > .env.livekit-domain << EOF
# Configuración de dominio para LiveKit
DOMAIN=$DOMAIN
LIVEKIT_URL=$LIVEKIT_URL
PUBLIC_IP=$PUBLIC_IP
LOCAL_IP=$LOCAL_IP
# Variables para EasyPanel/OpenVidu Meet:
LIVEKIT_URL=$LIVEKIT_URL
LIVEKIT_API_KEY=production-key
LIVEKIT_API_SECRET=tu-secret-de-32-caracteres
EOF
echo -e "${GREEN}"
echo "============================================="
echo "🎉 DOMINIO CONFIGURADO EXITOSAMENTE"
echo "============================================="
echo "🌐 Dominio: $DOMAIN"
echo "🔗 LiveKit URL: $LIVEKIT_URL"
echo "📍 IP Pública: $PUBLIC_IP"
echo "🏠 IP Local: $LOCAL_IP"
echo ""
echo "📋 CONFIGURACIÓN PARA OPENVIDU MEET:"
echo " LIVEKIT_URL=$LIVEKIT_URL"
echo ""
echo "🔧 PUERTOS NECESARIOS EN ROUTER:"
echo " TCP 7880 → $LOCAL_IP:7880"
echo " UDP 50000-50100 → $LOCAL_IP:50000-50100"
if [[ $DOMAIN_OPTION == 2 ]]; then
echo " TCP 80,443 → $LOCAL_IP:80,443"
fi
echo ""
echo "📁 Archivos generados:"
echo " - .env.livekit-domain (variables)"
if [[ $DOMAIN_OPTION == 1 ]]; then
echo " - update-duckdns.sh (actualización automática)"
fi
echo "============================================="
echo -e "${NC}"
# Test conectividad
echo -e "${BLUE}🔍 Probando conectividad...${NC}"
if timeout 5 bash -c "echo >/dev/tcp/$DOMAIN/7880" 2>/dev/null; then
echo -e "${GREEN}✅ Puerto 7880 accesible${NC}"
else
echo -e "${YELLOW}⚠️ Puerto 7880 no accesible (verificar port forwarding)${NC}"
fi

View File

@ -1,58 +0,0 @@
#!/bin/bash
# Script para configurar puertos UDP para LiveKit local
echo "🔧 Configurando puertos UDP para LiveKit..."
# Verificar si ufw está disponible
if command -v ufw &> /dev/null; then
echo "Configurando con UFW..."
# Puertos TCP para LiveKit API
sudo ufw allow 7880/tcp comment "LiveKit API"
# Rango de puertos UDP para WebRTC (según livekit.yaml)
sudo ufw allow 50000:60000/udp comment "LiveKit WebRTC UDP"
# Verificar reglas
echo "Reglas UFW configuradas:"
sudo ufw status numbered
elif command -v firewall-cmd &> /dev/null; then
echo "Configurando con firewalld..."
# Puerto TCP para LiveKit
sudo firewall-cmd --permanent --add-port=7880/tcp
# Rango UDP para WebRTC
sudo firewall-cmd --permanent --add-port=50000-60000/udp
# Recargar firewall
sudo firewall-cmd --reload
echo "Reglas firewalld configuradas:"
sudo firewall-cmd --list-ports
else
echo "⚠️ No se detectó UFW ni firewalld"
echo "Configurar manualmente:"
echo "- TCP 7880 (LiveKit API)"
echo "- UDP 50000-60000 (WebRTC media)"
fi
echo "✅ Configuración de firewall completada"
# Verificar que LiveKit esté corriendo
echo "🔍 Verificando LiveKit..."
if curl -s http://localhost:7880 > /dev/null 2>&1; then
echo "✅ LiveKit responde en puerto 7880"
else
echo "❌ LiveKit no responde - verificar que esté corriendo"
fi
# Mostrar puertos abiertos
echo "📊 Puertos actualmente en uso:"
if command -v ss &> /dev/null; then
ss -tulnp | grep -E "(7880|50000|60000)"
elif command -v netstat &> /dev/null; then
netstat -tulnp | grep -E "(7880|50000|60000)"
fi

View File

@ -1,136 +0,0 @@
#!/bin/bash
# Script para configurar UDP de forma segura según el caso de uso
set -e
# Colores
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}🔧 Configuración segura de puertos UDP para LiveKit${NC}"
echo ""
# Preguntar caso de uso
echo "¿Cuál es tu caso de uso?"
echo "1) Solo red local (recomendado y seguro)"
echo "2) Acceso desde internet (complejo y riesgoso)"
echo "3) Mostrar configuración actual"
echo ""
read -p "Selecciona opción (1-3): " OPTION
case $OPTION in
1)
echo -e "${GREEN}✅ Configurando para RED LOCAL únicamente${NC}"
# Configurar firewall para solo red local
if command -v ufw &> /dev/null; then
echo "Configurando UFW para red local..."
# Permitir desde red local
sudo ufw allow from 192.168.0.0/16 to any port 50000:60000 proto udp comment "LiveKit UDP (red local)"
sudo ufw allow from 192.168.0.0/16 to any port 7880 proto tcp comment "LiveKit API (red local)"
sudo ufw allow from 192.168.0.0/16 to any port 80 proto tcp comment "HTTP (red local)"
# DENEGAR acceso externo a UDP
sudo ufw deny 50000:60000/udp comment "BLOQUEAR UDP externo"
echo -e "${GREEN}✅ Firewall configurado para red local${NC}"
sudo ufw status numbered
else
echo -e "${YELLOW}⚠️ UFW no disponible. Configurar manualmente:${NC}"
echo "- Permitir UDP 50000-60000 desde 192.168.x.x"
echo "- BLOQUEAR UDP desde internet"
fi
echo ""
echo -e "${GREEN}🔒 CONFIGURACIÓN SEGURA APLICADA:${NC}"
echo "- UDP 50000-60000: Solo red local"
echo "- Acceso web: http://192.168.1.19"
echo "- Sin port forwarding necesario"
echo "- Máxima seguridad"
;;
2)
echo -e "${RED}⚠️ CONFIGURACIÓN PARA ACCESO PÚBLICO${NC}"
echo ""
echo -e "${YELLOW}RIESGOS:${NC}"
echo "- 10,000 puertos UDP expuestos"
echo "- Posibles ataques de red"
echo "- Configuración compleja"
echo "- Problemas con NAT/CGNAT"
echo ""
echo -e "${BLUE}ALTERNATIVAS RECOMENDADAS:${NC}"
echo "1. LiveKit Cloud (sin UDP local)"
echo "2. VPN para usuarios remotos"
echo "3. TURN server para NAT traversal"
echo ""
read -p "¿Continuar con configuración pública? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${RED}Configurando acceso público...${NC}"
if command -v ufw &> /dev/null; then
# Abrir UDP para todo el mundo (PELIGROSO)
sudo ufw allow 50000:60000/udp comment "LiveKit UDP PUBLICO"
sudo ufw allow 7880/tcp comment "LiveKit API PUBLICO"
sudo ufw allow 80/tcp comment "HTTP PUBLICO"
echo -e "${RED}❌ UDP EXPUESTO PÚBLICAMENTE${NC}"
fi
echo ""
echo -e "${RED}⚠️ CONFIGURACIÓN APLICADA (RIESGOSA):${NC}"
echo "- UDP 50000-60000: PÚBLICO"
echo "- Configurar port forwarding en router"
echo "- Usar IP pública en livekit.yaml"
echo "- Considerar VPN o LiveKit Cloud"
else
echo -e "${GREEN}✅ Configuración pública cancelada${NC}"
fi
;;
3)
echo -e "${BLUE}📊 Configuración actual:${NC}"
# Verificar puertos UDP
echo ""
echo "Puertos UDP en uso:"
if command -v ss &> /dev/null; then
ss -ulnp | grep -E ":(5[0-9]{4})" | head -10
fi
# Verificar firewall
echo ""
echo "Reglas de firewall:"
if command -v ufw &> /dev/null; then
sudo ufw status numbered | grep -E "(50000|7880|80)"
fi
# Verificar IP externa
echo ""
echo "IP externa detectada:"
curl -s ifconfig.me || echo "No disponible"
echo ""
echo "IP local:"
hostname -I | awk '{print $1}'
;;
*)
echo -e "${RED}❌ Opción inválida${NC}"
exit 1
;;
esac
echo ""
echo -e "${BLUE}💡 RECOMENDACIÓN FINAL:${NC}"
echo "Para máxima seguridad y simplicidad:"
echo "- Usar solo en red local"
echo "- Para acceso remoto: VPN o LiveKit Cloud"
echo "- NO exponer 10,000 puertos UDP públicamente"

View File

@ -1,100 +0,0 @@
#!/bin/bash
set -e
echo "🚀 PREPARANDO DEPLOY PARA EASYPANEL"
echo "==================================="
# 1. Crear directorio ssl
echo "1. Creando estructura de directorios..."
mkdir -p ssl logs
# 2. Crear certificados dummy (EasyPanel los reemplazará)
echo "2. Creando certificados dummy..."
if [ ! -f ssl/cert.pem ]; then
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/key.pem \
-out ssl/cert.pem \
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost" 2>/dev/null || \
echo "⚠️ OpenSSL no disponible - EasyPanel manejará SSL"
fi
# 3. Crear .dockerignore
echo "3. Optimizando build..."
cat > .dockerignore << 'EOF'
node_modules
.git
.env*
*.log
logs/
ssl/
*.md
.vscode
.idea
dist
coverage
.nyc_output
EOF
# 4. Verificar archivos necesarios
echo "4. Verificando archivos..."
REQUIRED_FILES=(
"Dockerfile"
"docker-compose.yml"
"nginx.conf"
".env.production"
)
for file in "${REQUIRED_FILES[@]}"; do
if [ -f "$file" ]; then
echo "$file"
else
echo "$file - FALTANTE"
exit 1
fi
done
# 5. Test de build local (opcional)
echo "5. ¿Quieres probar el build localmente? (y/n)"
read -r TEST_BUILD
if [ "$TEST_BUILD" = "y" ] || [ "$TEST_BUILD" = "Y" ]; then
echo "Construyendo imagen de prueba..."
docker build -t openvidu-meet-test . || {
echo "❌ Error en el build - revisar Dockerfile"
exit 1
}
echo "✅ Build exitoso"
fi
echo ""
echo "🎉 PREPARACIÓN COMPLETADA"
echo "========================="
echo ""
echo "📋 PASOS PARA EASYPANEL:"
echo ""
echo "1. Crear nuevo proyecto en EasyPanel"
echo "2. Conectar repositorio Git"
echo "3. Configurar variables de entorno:"
echo " - Copiar contenido de .env.production"
echo " - Ajustar LIVEKIT_URL y secrets"
echo ""
echo "4. Configurar build:"
echo " - Dockerfile: ./Dockerfile"
echo " - Puerto: 80 (nginx) o 6080 (directo)"
echo ""
echo "5. Configurar dominio y SSL en EasyPanel"
echo ""
echo "📁 ARCHIVOS LISTOS:"
echo " ✅ Dockerfile (multi-stage optimizado)"
echo " ✅ docker-compose.yml (con nginx proxy)"
echo " ✅ nginx.conf (configuración completa)"
echo " ✅ .env.production (variables de ejemplo)"
echo ""
echo "🔗 URLs después del deploy:"
echo " • Admin: https://tu-dominio.com"
echo " • API: https://tu-dominio.com/api/"
echo " • Health: https://tu-dominio.com/nginx-health"
echo ""
echo "👤 Login por defecto:"
echo " • Usuario: admin"
echo " • Contraseña: [configurar en ADMIN_PASSWORD]"

View File

@ -1,221 +0,0 @@
#!/bin/bash
# Script para desplegar LiveKit self-hosted con exposición pública
set -e
# Colores
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}🏠 Configurando LiveKit Self-Hosted con exposición pública${NC}"
echo ""
# Detectar IP local
LOCAL_IP=$(hostname -I | awk '{print $1}')
echo -e "${BLUE}🌐 IP Local detectada: $LOCAL_IP${NC}"
# Preguntar dominio/IP pública
echo "¿Cuál es tu configuración de acceso público?"
echo "1) Tengo IP pública fija"
echo "2) IP dinámica - usar DuckDNS"
echo "3) Solo testing local"
echo ""
read -p "Selecciona opción (1-3): " IP_OPTION
case $IP_OPTION in
1)
read -p "Ingresa tu IP pública: " PUBLIC_IP
EXTERNAL_HOST="$PUBLIC_IP"
;;
2)
read -p "Ingresa tu subdominio DuckDNS (ej: mi-livekit): " DUCKDNS_SUBDOMAIN
EXTERNAL_HOST="$DUCKDNS_SUBDOMAIN.duckdns.org"
echo -e "${YELLOW}📝 Recuerda configurar DuckDNS token después${NC}"
;;
3)
EXTERNAL_HOST="$LOCAL_IP"
echo -e "${YELLOW}⚠️ Solo funcionará en red local${NC}"
;;
*)
echo -e "${RED}❌ Opción inválida${NC}"
exit 1
;;
esac
echo -e "${GREEN}🌐 Host externo configurado: $EXTERNAL_HOST${NC}"
# Generar secretos seguros
API_SECRET=$(openssl rand -hex 32)
REDIS_PASSWORD=$(openssl rand -hex 16)
echo -e "${YELLOW}🔧 Generando configuración...${NC}"
# Crear directorio SSL
mkdir -p ssl logs
# Generar livekit-production.yaml
cat > livekit-production.yaml << EOF
port: 7880
bind_addresses: ["0.0.0.0"]
# API Keys seguros (generados automáticamente)
keys:
production-key: $API_SECRET
# Redis para persistence y scaling
redis:
address: "redis:6379"
password: "$REDIS_PASSWORD"
db: 0
# RTC Configuration para acceso público
rtc:
# Rango de puertos UDP reducido pero suficiente
port_range_start: 50000
port_range_end: 50100
# Host/IP externa para acceso público
use_external_ip: true
external_ip: "$EXTERNAL_HOST"
# STUN servers para NAT traversal
ice_servers:
- urls: ["stun:stun.l.google.com:19302"]
- urls: ["stun:stun1.l.google.com:19302"]
# Room settings para producción
room:
auto_create: true
max_participants: 25
empty_timeout: 600
# Logging para producción
log_level: info
log_format: json
EOF
# Crear docker-compose-livekit-server.yml
cat > docker-compose-livekit-server.yml << EOF
version: '3.8'
services:
livekit-server:
image: livekit/livekit-server:latest
container_name: livekit-production
restart: unless-stopped
ports:
- "7880:7880"
- "50000-50100:50000-50100/udp"
volumes:
- ./livekit-production.yaml:/livekit.yaml:ro
- ./logs:/app/logs
command: --config /livekit.yaml
networks:
- livekit-network
depends_on:
- redis
redis:
image: redis:7-alpine
container_name: livekit-redis
restart: unless-stopped
ports:
- "6379:6379"
command: redis-server --requirepass $REDIS_PASSWORD
volumes:
- redis_data:/data
networks:
- livekit-network
volumes:
redis_data:
networks:
livekit-network:
driver: bridge
EOF
# Crear variables para OpenVidu Meet
cat > .env.livekit-client << EOF
# Variables para EasyPanel/OpenVidu Meet
LIVEKIT_URL=ws://$EXTERNAL_HOST:7880
LIVEKIT_API_KEY=production-key
LIVEKIT_API_SECRET=$API_SECRET
EOF
echo -e "${GREEN}✅ Configuración generada${NC}"
# Configurar firewall
echo -e "${YELLOW}🔥 Configurando firewall...${NC}"
if command -v ufw &> /dev/null; then
sudo ufw allow 7880/tcp comment "LiveKit API"
sudo ufw allow 50000:50100/udp comment "LiveKit WebRTC"
echo -e "${GREEN}✅ Firewall configurado${NC}"
fi
# Parar servicios existentes
echo -e "${YELLOW}🛑 Parando servicios existentes...${NC}"
docker-compose -f docker-compose-livekit-server.yml down 2>/dev/null || true
# Iniciar LiveKit Server
echo -e "${YELLOW}🚀 Iniciando LiveKit Server...${NC}"
docker-compose -f docker-compose-livekit-server.yml up -d
# Esperar inicio
echo -e "${YELLOW}⏳ Esperando que LiveKit inicie...${NC}"
sleep 15
# Verificar servicios
echo -e "${BLUE}🔍 Verificando servicios...${NC}"
if curl -s http://localhost:7880 > /dev/null 2>&1; then
echo -e "${GREEN}✅ LiveKit API funcionando${NC}"
else
echo -e "${RED}❌ LiveKit no responde${NC}"
fi
if docker exec livekit-redis redis-cli -a $REDIS_PASSWORD ping > /dev/null 2>&1; then
echo -e "${GREEN}✅ Redis funcionando${NC}"
else
echo -e "${RED}❌ Redis no responde${NC}"
fi
# Mostrar configuración final
echo -e "${GREEN}"
echo "============================================="
echo "🎉 LIVEKIT SELF-HOSTED CONFIGURADO"
echo "============================================="
echo "🌐 Host externo: $EXTERNAL_HOST"
echo "🔌 Puerto API: 7880"
echo "📡 Puertos UDP: 50000-50100"
echo ""
echo "📋 CONFIGURACIÓN PARA OPENVIDU MEET:"
echo " LIVEKIT_URL=ws://$EXTERNAL_HOST:7880"
echo " LIVEKIT_API_KEY=production-key"
echo " LIVEKIT_API_SECRET=$API_SECRET"
echo ""
echo "🔧 PASOS SIGUIENTES:"
echo "1. Configurar port forwarding en router:"
echo " - TCP 7880 → $LOCAL_IP:7880"
echo " - UDP 50000-50100 → $LOCAL_IP:50000-50100"
echo ""
if [[ $IP_OPTION == 2 ]]; then
echo "2. Configurar DuckDNS:"
echo " - Token en duckdns.org"
echo " - Script de actualización automática"
echo ""
fi
echo "3. Configurar OpenVidu Meet con variables generadas"
echo "4. (Opcional) Configurar SSL/HTTPS con Let's Encrypt"
echo "============================================="
echo -e "${NC}"
# Mostrar logs
read -p "¿Ver logs de LiveKit en tiempo real? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
docker-compose -f docker-compose-livekit-server.yml logs -f livekit-server
fi

View File

@ -1,125 +0,0 @@
#!/bin/bash
# Script completo para desplegar OpenVidu Meet con LiveKit local y UDP
set -e
echo "🚀 Desplegando OpenVidu Meet con LiveKit local (UDP)..."
# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Verificar Docker
if ! command -v docker &> /dev/null; then
echo -e "${RED}❌ Docker no está instalado${NC}"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
echo -e "${RED}❌ Docker Compose no está instalado${NC}"
exit 1
fi
# Obtener IP local
LOCAL_IP=$(hostname -I | awk '{print $1}')
echo -e "${BLUE}🌐 IP Local detectada: $LOCAL_IP${NC}"
# Crear .env para local
echo -e "${YELLOW}📝 Creando configuración local...${NC}"
cat > .env.local << EOF
# Configuración LOCAL con LiveKit y UDP
ADMIN_PASSWORD=admin123
REDIS_PASSWORD=redispassword
# LiveKit Local
LIVEKIT_URL=ws://$LOCAL_IP:7880
LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=secretsecretsecretsecretsecretsecret
# Redis Local
REDIS_HOST=$LOCAL_IP
REDIS_PORT=6379
EOF
# Actualizar IP en livekit-local.yaml
echo -e "${YELLOW}🔧 Configurando LiveKit para IP $LOCAL_IP...${NC}"
sed -i "s/external_ip: \".*\"/external_ip: \"$LOCAL_IP\"/" livekit-local.yaml
# Configurar firewall
echo -e "${YELLOW}🔥 Configurando firewall...${NC}"
./configure-udp-ports.sh
# Parar servicios existentes
echo -e "${YELLOW}🛑 Parando servicios existentes...${NC}"
docker-compose -f docker-compose-with-livekit.yml down 2>/dev/null || true
# Construir imágenes
echo -e "${YELLOW}🔨 Construyendo imágenes...${NC}"
docker-compose -f docker-compose-with-livekit.yml build
# Iniciar servicios
echo -e "${YELLOW}🚀 Iniciando servicios completos...${NC}"
docker-compose -f docker-compose-with-livekit.yml --env-file .env.local up -d
# Esperar a que los servicios estén listos
echo -e "${YELLOW}⏳ Esperando servicios...${NC}"
sleep 15
# Verificar servicios
echo -e "${BLUE}🔍 Verificando servicios...${NC}"
services=(
"redis:6379"
"livekit:7880"
"openvidu-meet:6080"
"nginx:80"
)
for service in "${services[@]}"; do
name=$(echo $service | cut -d: -f1)
port=$(echo $service | cut -d: -f2)
if curl -s http://localhost:$port > /dev/null 2>&1; then
echo -e "${GREEN}$name funcionando en puerto $port${NC}"
else
echo -e "${RED}$name no responde en puerto $port${NC}"
fi
done
# Verificar puertos UDP
echo -e "${BLUE}📊 Verificando puertos UDP...${NC}"
if ss -tulnp | grep -q ":50000-60000"; then
echo -e "${GREEN}✅ Puertos UDP 50000-60000 abiertos${NC}"
else
echo -e "${YELLOW}⚠️ No se detectan puertos UDP - verificar manualmente${NC}"
fi
# Mostrar URLs finales
echo -e "${GREEN}"
echo "============================================="
echo "🎉 DESPLIEGUE COMPLETADO"
echo "============================================="
echo "📱 OpenVidu Meet: http://$LOCAL_IP"
echo "👨‍💼 Admin Panel: http://$LOCAL_IP/admin"
echo "🔧 LiveKit API: http://$LOCAL_IP:7880"
echo "📊 Redis: $LOCAL_IP:6379"
echo ""
echo "🔐 Credenciales Admin:"
echo " Usuario: admin"
echo " Password: admin123"
echo ""
echo "⚠️ PUERTOS NECESARIOS:"
echo " TCP: 80, 6080, 6379, 7880"
echo " UDP: 50000-60000 (WebRTC)"
echo "============================================="
echo -e "${NC}"
# Mostrar logs en tiempo real (opcional)
read -p "¿Ver logs en tiempo real? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
docker-compose -f docker-compose-with-livekit.yml --env-file .env.local logs -f
fi

View File

@ -1,94 +0,0 @@
version: '3.8'
services:
# OpenVidu Meet Backend
openvidu-meet:
build: .
container_name: openvidu-meet
restart: unless-stopped
environment:
NODE_ENV: production
MEET_LOG_LEVEL: info
MEET_BLOB_STORAGE_MODE: memory
PORT: 6080
# Admin user
MEET_INITIAL_ADMIN_USER: admin
MEET_INITIAL_ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin123}
# CORS y proxy
SERVER_CORS_ORIGIN: "*"
TRUST_PROXY: "true"
# LiveKit LOCAL con UDP
LIVEKIT_URL: ${LIVEKIT_URL:-ws://192.168.1.19:7880}
LIVEKIT_API_KEY: ${LIVEKIT_API_KEY:-devkey}
LIVEKIT_API_SECRET: ${LIVEKIT_API_SECRET:-secretsecretsecretsecretsecretsecret}
ports:
- "6080:6080"
volumes:
- ./logs:/app/logs
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:6080/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
- openvidu-network
# LiveKit Server LOCAL con puertos UDP
livekit:
image: livekit/livekit-server:latest
container_name: openvidu-livekit
restart: unless-stopped
ports:
# Puerto API/WebSocket
- "7880:7880"
# Rango UDP para WebRTC (IMPORTANTE!)
- "50000-60000:50000-60000/udp"
volumes:
- ./livekit.yaml:/livekit.yaml:ro
command: --config /livekit.yaml
networks:
- openvidu-network
depends_on:
- redis
# Redis para LiveKit
redis:
image: redis:7-alpine
container_name: openvidu-redis
restart: unless-stopped
ports:
- "6379:6379"
command: redis-server --requirepass ${REDIS_PASSWORD:-redispassword}
volumes:
- redis_data:/data
networks:
- openvidu-network
# Nginx Proxy
nginx-proxy:
image: nginx:alpine
container_name: openvidu-nginx
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- nginx-cache:/var/cache/nginx
depends_on:
- openvidu-meet
- livekit
networks:
- openvidu-network
volumes:
nginx-cache:
redis_data:
networks:
openvidu-network:
driver: bridge

View File

@ -1,70 +0,0 @@
version: '3.8'
services:
# OpenVidu Meet Backend
openvidu-meet:
build: .
container_name: openvidu-meet-ce
restart: unless-stopped
environment:
# Configuración básica
NODE_ENV: production
MEET_LOG_LEVEL: info
MEET_BLOB_STORAGE_MODE: memory
PORT: 6080
# Admin user (cambiar en producción)
MEET_INITIAL_ADMIN_USER: admin
MEET_INITIAL_ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin123}
# CORS para proxy
SERVER_CORS_ORIGIN: "*"
# Configuración para proxy
TRUST_PROXY: "true"
# LiveKit (ajustar según tu setup)
LIVEKIT_URL: ${LIVEKIT_URL:-ws://localhost:7880}
LIVEKIT_API_KEY: ${LIVEKIT_API_KEY:-devkey}
LIVEKIT_API_SECRET: ${LIVEKIT_API_SECRET:-your-secret-key-32-chars-long}
# Redis (opcional - si no se proporciona, usa memoria)
MEET_REDIS_HOST: ${REDIS_HOST:-}
MEET_REDIS_PORT: ${REDIS_PORT:-6379}
MEET_REDIS_PASSWORD: ${REDIS_PASSWORD:-}
ports:
- "6080:6080"
volumes:
# Logs persistentes
- ./logs:/app/logs
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:6080/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
- openvidu-network
# Nginx Proxy - Solo puerto 80 para EasyPanel
nginx-proxy:
image: nginx:alpine
container_name: openvidu-nginx
restart: unless-stopped
ports:
- "80:80" # Solo HTTP - EasyPanel maneja SSL con Traefik
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- nginx-cache:/var/cache/nginx
depends_on:
- openvidu-meet
networks:
- openvidu-network
volumes:
nginx-cache:
networks:
openvidu-network:
driver: bridge

View File

@ -1,178 +0,0 @@
# Javascript snippets
- `np` - nextPage
- `npssp` - nextPageServerSideProps
- `npsp` - nextPageStaticProps
- `npspth` - nextPageStaticPaths
- `nssp` - nextServerSideProps
- `nsp` - nextStaticProps
- `nspth` - nextStaticPaths
- `nip` - nextInitialProps
- `nimg` - nextImage
- `napp` - nextApp
- `ndoc` - nextDocument
- `napi` - nextApi
- `nmid` - nextMiddleware
## `np` - nextPage
```javascript
const FileName = ({}) => {
return <div></div>
}
export default FileName
```
## `npssp` - nextPageServerSideProps
```javascript
const FileName = ({}) => {
return <div></div>
}
export const getServerSideProps = async (ctx) => {
return {
props: {}
}
}
export default FileName
```
## `npsp` - nextPageStaticProps
```javascript
const FileName = ({}) => {
return <div></div>
}
export const getStaticProps = async (ctx) => {
return {
props: {},
}
}
export default FileName
```
## `npspth` - nextPageStaticPaths
```javascript
const FileName = ({}) => {
return <div></div>
}
export const getStaticPaths = async () => {
return {
paths: [],
fallback: false,
}
}
export default FileName
```
## `nssp` - nextServerSideProps
```javascript
export const getServerSideProps = async (ctx) => {
return {
props: {}
}
}
```
## `nsp` - nextStaticProps
```javascript
export const getStaticProps = async (ctx) => {
return {
props: {},
}
}
```
## `nspth` - nextStaticPaths
```javascript
export const getStaticPaths = async () => {
return {
paths: [],
fallback: false,
}
}
```
## `nip` - nextInitialProps
```javascript
FileName.getInitialProps = async (ctx) => {
return {
}
}
```
## `nimg` - nextImage
```javascript
<Image src="" alt="" />
```
## `napp` - nextApp
```javascript
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
```
## `ndoc` - nextDocument
```javascript
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument
```
## `napi` - nextApi
```javascript
export default async function handler(req, res) {
}
```
## `nmid` - nextMiddleware
```javascript
import { NextResponse } from 'next/server'
export async function middleware(request) {
}
export const config = {
matcher: '/about/:path*',
}
```

View File

@ -1,202 +0,0 @@
# Typescript snippets
- `np` - nextPage
- `npssp` - nextPageServerSideProps
- `npsp` - nextPageStaticProps
- `npspth` - nextPageStaticPaths
- `nssp` - nextServerSideProps
- `nsp` - nextStaticProps
- `nspth` - nextStaticPaths
- `nip` - nextInitialProps
- `nimg` - nextImage
- `napp` - nextApp
- `ndoc` - nextDocument
- `napi` - nextApi
- `nmid` - nextMiddleware
## `np` - nextPage
```typescript
import { NextPage } from 'next'
interface Props {}
const FileName: NextPage<Props> = ({}) => {
return <div></div>
}
export default FileName
```
## `npssp` - nextPageServerSideProps
```typescript
import { NextPage, GetServerSideProps } from 'next'
interface Props {}
const FileName: NextPage<Props> = ({}) => {
return <div></div>
}
export const getServerSideProps: GetServerSideProps = async (ctx) => {
return {
props: {}
}
}
export default FileName
```
## `npsp` - nextPageStaticProps
```typescript
import { NextPage, GetStaticProps } from 'next'
interface Props {}
const FileName: NextPage<Props> = ({}) => {
return <div></div>
}
export const getStaticProps: GetStaticProps = async (ctx) => {
return {
props: {},
}
}
export default FileName
```
## `npspth` - nextPageStaticPaths
```typescript
import { NextPage, GetStaticPaths } from 'next'
interface Props {}
const FileName: NextPage<Props> = ({}) => {
return <div></div>
}
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: false,
}
}
export default FileName
```
## `nssp` - nextServerSideProps
```typescript
export const getServerSideProps: GetServerSideProps = async (ctx) => {
return {
props: {}
}
}
```
## `nsp` - nextStaticProps
```typescript
export const getStaticProps: GetStaticProps = async (ctx) => {
return {
props: {},
}
}
```
## `nspth` - nextStaticPaths
```typescript
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: false,
}
}
```
## `nip` - nextInitialProps
```typescript
FileName.getInitialProps = async (ctx) => {
return {
}
}
```
## `nimg` - nextImage
```typescript
<Image src="" alt="" />
```
## `napp` - nextApp
```typescript
import type { AppProps } from 'next/app'
export default function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
```
## `ndoc` - nextDocument
```typescript
import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument
```
## `napi` - nextApi
```typescript
import type { NextApiRequest, NextApiResponse } from 'next'
interface Data {}
export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
}
```
## `nmid` - nextMiddleware
```typescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
}
export const config = {
matcher: '/about/:path*',
}
```

View File

@ -1,68 +0,0 @@
#!/bin/bash
set -e
echo "🔧 SOLUCIONANDO PROBLEMA DE LOGIN ADMIN"
echo "======================================"
echo "1. Parando backend actual..."
pkill -f "node.*dist/src/server.js" 2>/dev/null || true
sleep 3
echo "2. Configurando backend con storage en memoria..."
cd /home/xesar/Documentos/openvidu-meet/meet-ce/backend
# Crear backup del log anterior
[ -f /tmp/ovm-logs/backend.log ] && mv /tmp/ovm-logs/backend.log /tmp/ovm-logs/backend.log.backup
echo "3. Arrancando backend con configuración correcta..."
nohup env \
NODE_ENV=development \
MEET_LOG_LEVEL=debug \
MEET_BLOB_STORAGE_MODE=memory \
MEET_INITIAL_ADMIN_USER=admin \
MEET_INITIAL_ADMIN_PASSWORD=admin \
LIVEKIT_URL=ws://192.168.1.19:7880 \
LIVEKIT_URL_PRIVATE=ws://192.168.1.19:7880 \
LIVEKIT_API_KEY=devkey \
LIVEKIT_API_SECRET=secretsecretsecretsecretsecretsecret \
MEET_REDIS_HOST=192.168.1.19 \
MEET_REDIS_PORT=6379 \
MEET_REDIS_PASSWORD=redispassword \
node dist/src/server.js > /tmp/ovm-logs/backend.log 2>&1 &
BACKEND_PID=$!
echo "✅ Backend iniciado con PID: $BACKEND_PID"
echo "4. Esperando arranque (10s)..."
sleep 10
echo "5. Verificando estado:"
if ps -p $BACKEND_PID >/dev/null 2>&1; then
echo "✅ Proceso backend activo"
else
echo "❌ Proceso backend inactivo"
echo "Logs de error:"
tail -n 10 /tmp/ovm-logs/backend.log
exit 1
fi
if ss -ltn | grep -q :6080; then
echo "✅ Puerto 6080 activo"
else
echo "❌ Puerto 6080 inactivo"
fi
echo "6. Verificando logs de admin:"
grep -i "admin\|storage.*mode\|memory" /tmp/ovm-logs/backend.log | tail -5
echo ""
echo "🎉 SOLUCION COMPLETADA"
echo "======================"
echo "✅ Backend corriendo con storage en memoria"
echo "✅ Usuario admin configurado: admin/admin"
echo "🌐 Accede a: http://192.168.1.19:6080"
echo "📄 Logs en: /tmp/ovm-logs/backend.log"
echo ""
echo "👤 CREDENCIALES DE LOGIN:"
echo " Usuario: admin"
echo " Contraseña: admin"

View File

@ -1,46 +0,0 @@
# LiveKit Server Configuration for LOCAL deployment with UDP
# Para usar con Docker Compose completo incluyendo LiveKit
port: 7880
bind_addresses: [""]
# API Keys (mismo secret que en backend)
keys:
devkey: secretsecretsecretsecretsecretsecret
# Redis para coordinación
redis:
address: redis:6379
password: redispassword
db: 0
# Configuración RTC con UDP para red local
rtc:
# Rango de puertos UDP (DEBE coincidir con docker-compose)
port_range_start: 50000
port_range_end: 60000
# IP externa para acceso desde otros dispositivos
# Cambiar por tu IP local real
use_external_ip: true
external_ip: "192.168.1.19"
# Configuración ICE/STUN
ice_servers:
- urls: ["stun:stun.l.google.com:19302"]
# Configuración de rooms
room:
auto_create: true
max_participants: 0
empty_timeout: 300
# Egress para grabaciones (requiere Redis)
# Habilitado automáticamente con Redis
# Logging
log_level: info
log_format: json
# Configuración de desarrollo
development: true

View File

@ -1,41 +0,0 @@
# LiveKit Server Configuration for Development
# https://docs.livekit.io/deploy/configuration/
port: 7880
# Admin/API port (HTTP for rooms/egress APIs)
# The default admin port is 7880 for WebSocket and HTTP admin API
# Some builds use separate ports; adjust if needed
# API Keys for authentication (secret must be 32+ characters)
keys:
devkey: secretsecretsecretsecretsecretsecret
# Redis configuration (required for egress, ingress, and multi-node deployments)
redis:
address: 192.168.1.20:6380
password: 52a4a5b5efdd2ac4a8fd
db: 0
# Enable egress service (recording/streaming)
# Egress requires Redis to coordinate recording jobs
# If you see "egress not connected (redis required)", ensure Redis config is correct above
# Development mode settings
log_level: debug
# RTC configuration
rtc:
# Use ephemeral ports for UDP
port_range_start: 50000
port_range_end: 60000
# Allow connection from network (not just localhost)
use_external_ip: true
# Room settings
room:
# Auto-create rooms when participants join
auto_create: true
# Max participants per room (0 = unlimited)
max_participants: 0
# Empty room timeout (in seconds, 0 = no timeout)
empty_timeout: 300

View File

@ -1,8 +1,9 @@
{
"jest.jestCommandLine": "node --experimental-vm-modules ../../node_modules/.bin/jest",
"jest.jestCommandLine": "node --experimental-vm-modules ../../node_modules/.bin/jest --config jest.integration.config.mjs",
"jest.rootPath": "backend",
"jest.nodeEnv": {
"NODE_OPTIONS": "--experimental-vm-modules"
},
"jest.runMode": "on-demand"
}

View File

@ -1,39 +1,4 @@
USE_HTTPS=true
USE_HTTPS=false
MEET_LOG_LEVEL=debug
SERVER_CORS_ORIGIN=*
MEET_INITIAL_API_KEY=meet-api-key
# Admin user configuration (initial admin user created on first startup)
MEET_INITIAL_ADMIN_USER=admin
MEET_INITIAL_ADMIN_PASSWORD=admin
# Redis configuration (used by the backend). Defaults in code point to localhost:6379.
# If you don't have a Redis server running locally, you can start one with Docker:
# docker run --name openvidu-redis -p 6379:6379 -d redis:7
# Or with podman:
# podman run --name openvidu-redis -p 6379:6379 -d docker.io/library/redis:7
# Environment variables read by the server (optional - only needed if you want to change defaults):
MEET_REDIS_HOST=192.168.1.19
MEET_REDIS_PORT=6379
MEET_REDIS_PASSWORD=redispassword
MEET_REDIS_DB=0
# If using Redis Sentinel, set the host list as comma separated host:port pairs and the sentinel password:
# MEET_REDIS_SENTINEL_HOST_LIST=sentinel1:26379,sentinel2:26379
# MEET_REDIS_SENTINEL_PASSWORD=your-sentinel-password
# LiveKit URL — use the websocket URL that corresponds to the admin HTTP port.
# The livekit-server process here is listening on 7880 (client) and 7881 (admin).
# Point LIVEKIT_URL/LIVEKIT_URL_PRIVATE to the admin-enabled port so server-side
# clients (egress/room service) use the correct HTTP admin endpoint.
LIVEKIT_URL=ws://nextream.sytes.net:7880
LIVEKIT_URL_PRIVATE=ws://nextream.sytes.net:7880
LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=secretsecretsecretsecretsecretsecret
# MinIO / S3 configuration for local development (temporarily using memory)
MEET_BLOB_STORAGE_MODE=memory
# MEET_S3_SERVICE_ENDPOINT=http://192.168.1.19:9000
# MEET_S3_ACCESS_KEY=minioadmin
# MEET_S3_SECRET_KEY=minioadmin
# MEET_S3_BUCKET=openvidu-appdata
# MEET_S3_WITH_PATH_STYLE_ACCESS=true
MEET_INITIAL_API_KEY=meet-api-key

View File

@ -1,6 +1,7 @@
USE_HTTPS=false
MEET_LOG_LEVEL=verbose
MEET_LOG_LEVEL=debug
SERVER_CORS_ORIGIN=*
MEET_INITIAL_API_KEY=meet-api-key
MEET_INITIAL_WEBHOOK_ENABLED=true
MEET_INITIAL_WEBHOOK_URL=http://localhost:5080/webhook
MEET_INITIAL_WEBHOOK_URL=http://localhost:5080/webhook
MEETING_DEPARTURE_TIMEOUT=1s

View File

@ -23,9 +23,26 @@ pnpm install
pnpm run build:prod
```
## Storage Structure
## Storage Architecture
The OpenVidu Meet backend uses an S3 bucket to store all application data, including rooms, recordings, user information, and system config. The bucket follows a hierarchical structure organized as follows:
The OpenVidu Meet backend uses **MongoDB** as its primary data storage system for all application data, including rooms, recordings, user information, API keys, and system configuration.
### MongoDB Collections
The application manages the following MongoDB collections:
- **`meetglobalconfigs`**: System-wide configuration (singleton collection)
- **`meetusers`**: User accounts with authentication and roles
- **`meetapikeys`**: API keys for authentication
- **`meetrooms`**: Room configurations and metadata
- **`meetrecordings`**: Recording metadata and access information
- **`meetmigrations`**: Migration tracking for data and schema migrations
Each document in these collections includes a `schemaVersion` field for schema evolution tracking (internal use only, not exposed via API).
### Legacy Storage (S3/ABS/GCS)
Prior versions of OpenVidu Meet used cloud object storage (S3, Azure Blob Storage, or Google Cloud Storage) for data persistence. The legacy storage structure followed this organization:
### Bucket Structure
@ -109,6 +126,45 @@ Where:
This naming convention ensures uniqueness and provides traceability between the recording file, its metadata, and the originating room session.
---
## Data Migration System
OpenVidu Meet includes a comprehensive migration system to handle data persistence changes and schema evolution.
### Legacy Storage to MongoDB Migration
On first startup, the application automatically migrates existing data from legacy storage (S3/Azure Blob Storage/Google Cloud Storage) to MongoDB. This migration:
- **Runs automatically** on application startup if legacy storage is configured
- **Is idempotent** - safe to run multiple times (skips already migrated data)
- **Preserves all data** - rooms, recordings, users, API keys, and global config
- **Tracks progress** in the `meetmigrations` collection
- **Is HA-safe** using distributed locks to prevent concurrent migrations
### MongoDB Schema Migration System
The application uses a schema versioning system to safely evolve MongoDB document structures over time. This system:
- **Runs automatically** at startup before accepting requests
- **Tracks schema versions** via the `schemaVersion` field in each document
- **Supports forward-only migrations** (v1 → v2 → v3)
- **Processes in batches** for efficiency with large collections
- **Is HA-safe** using distributed locks
- **Validates before execution** to ensure migration safety
Schema migrations handle scenarios like:
- Adding new required fields with default values
- Removing deprecated fields
- Renaming or restructuring fields
- Data type transformations
For detailed information about creating and managing schema migrations, see:
📖 **[Schema Migration Documentation](./src/migrations/README.md)**
---
## Recordings
The recording feature is based on the following key concepts:
@ -140,10 +196,10 @@ flowchart TD
L -- "Error (recording not found, already stopped,\nor unknown error)" --> O["Reject Request"] --> J
```
4. **Failure handling**:
3. **Failure handling**:
If an OpenVidu instance crashes while a recording is active, the lock remains in place. This scenario can block subsequent recording attempts if the lock is not released promptly. To mitigate this issue, a lock garbage collector is implemented to periodically clean up orphaned locks.
The garbage collector runs when the OpenVidu deployment starts, and then every 30 minutes.
The garbage collector runs when the OpenVidu deployment starts, and then every 15 minutes.
```mermaid
graph TD;
@ -169,46 +225,53 @@ graph TD;
L --> M
M -->|More rooms| E
M -->|No more rooms| N[Process completed]
```
5. **Stale recordings cleanup**:
To handle recordings that become stale due to network issues, LiveKit or Egress crashes, or other unexpected situations, a separate cleanup process runs every 15 minutes to identify and abort recordings that haven't been updated within a configured threshold (5 minutes by default).
4. **Stale recordings cleanup**:
To handle recordings that become stale due to network issues, LiveKit or Egress crashes, or other unexpected situations, a separate cleanup process runs every 14 minutes to identify and abort recordings that haven't been updated within a configured threshold (5 minutes by default).
```mermaid
graph TD;
A[Initiate stale recordings cleanup] --> B[Get all in-progress recordings from LiveKit]
A[Initiate stale recordings cleanup] --> B[Get all active recordings from database<br/>ACTIVE or ENDING status]
B -->|Error| C[Log error and exit]
B -->|No recordings found| D[Log and exit]
B -->|Recordings found| E[Process recordings in batches of 10]
E --> F[For each recording in batch]
F --> G[Extract recording ID and updatedAt]
G --> H[Get recording status from storage]
F --> G[Extract recordingId, roomId and egressId]
G --> H[Check for corresponding egress in LiveKit]
H -->|Recording already ABORTED| I[Mark as already processed]
H -->|Recording active| J[Check if updatedAt exists]
H -->|No egress found| I[Recording is stale - no egress exists]
H -->|Egress exists| J[Extract updatedAt from egress]
J -->|No updatedAt timestamp| K[Keep as fresh - log warning]
J -->|Has updatedAt| L[Calculate if stale]
I --> K[Update status to ABORTED in database]
K --> L[Log successful abort - no egress found]
L -->|Still fresh| M[Log as fresh]
L -->|Is stale| N[Abort stale recording]
J -->|No updatedAt timestamp| M[Keep as fresh - log warning]
J -->|Has updatedAt| N[Check if recording age is stale]
N --> O[Update status to ABORTED in storage]
N --> P[Stop egress in LiveKit]
O --> Q[Log successful abort]
P --> Q
N -->|Age not stale| O[Log as fresh]
N -->|Age is stale| P[Check room existence]
I --> R[Continue to next recording]
K --> R
M --> R
Q --> R
P -->|Room does not exist| Q[Mark as stale]
P -->|Room exists| R[Check if room has participants]
R -->|More recordings in batch| F
R -->|Batch complete| S[Process next batch]
S -->|More batches| E
S -->|All batches processed| T[Log completion metrics]
T --> U[Process completed]
R -->|No participants| Q
R -->|Has participants| O
Q --> S[Update status to ABORTED in database]
Q --> T[Stop egress in LiveKit]
S --> U[Log successful abort]
T --> U
L --> V[Continue to next recording]
M --> V
O --> V
U --> V
V -->|More recordings in batch| F
V -->|Batch complete| W[Process next batch]
W -->|More batches| E
W -->|All batches processed| X[Log completion metrics]
X --> Y[Process completed]
```

View File

@ -1,9 +1,15 @@
export * from './src/routes/index.js';
export * from './src/controllers/index.js';
export * from './src/services/index.js';
export * from './src/models/index.js';
export * from './src/helpers/index.js';
// Main entry point for @openvidu-meet/backend package
export * from './src/config/internal-config.js';
export * from './src/environment.js';
export * from './src/server.js';
// Export other modules as needed
export * from './src/config/index.js';
export * from './src/controllers/index.js';
export * from './src/helpers/index.js';
export * from './src/middlewares/index.js';
export * from './src/models/index.js';
export * from './src/routes/index.js';
export * from './src/services/index.js';
export * from './src/utils/index.js';

View File

@ -15,16 +15,19 @@ const jestConfig = {
'^(\\.{1,2}/.*)\\.js$': '$1' // Allow importing js files and resolving to ts files
},
transform: {
'^.+\\.tsx?$': ['ts-jest', {
tsconfig: {
module: 'esnext',
moduleResolution: 'node16',
esModuleInterop: true,
allowSyntheticDefaultImports: true,
isolatedModules: true
},
useESM: true
}]
'^.+\\.tsx?$': [
'ts-jest',
{
tsconfig: {
module: 'esnext',
moduleResolution: 'node16',
esModuleInterop: true,
allowSyntheticDefaultImports: true,
isolatedModules: true
},
useESM: true
}
]
}
};

View File

@ -0,0 +1,12 @@
import baseConfig from './jest.config.mjs';
const integrationConfig = {
...baseConfig,
runInBand: true,
forceExit: true,
detectOpenHandles: true,
testMatch: ['**/tests/integration/**/*.(spec|test).ts'],
};
export default integrationConfig;

View File

@ -1,8 +0,0 @@
env: \t: No existe el fichero o el directorio
env: use -[v]S to pass options in shebang lines
env: \t: No existe el fichero o el directorio
env: use -[v]S to pass options in shebang lines
env: : No existe el fichero o el directorio
env: use -[v]S to pass options in shebang lines
env: \t: No existe el fichero o el directorio
env: use -[v]S to pass options in shebang lines

View File

@ -1,6 +0,0 @@
description: >
The cookie containing the access token.
This cookie is used to authenticate the user in subsequent requests.
schema:
type: string
example: 'OvMeetAccessToken=token_123456; Path=/; HttpOnly; SameSite=Strict'

View File

@ -1,6 +0,0 @@
description: >
The cookie containing the participant token.
This cookie is used to authenticate the participant in the room.
schema:
type: string
example: 'OvMeetParticipantToken=token_123456; Path=/; HttpOnly; SameSite=Strict'

View File

@ -1,6 +0,0 @@
description: >
The cookie containing the recording token.
This cookie is used to access the recordings in a room.
schema:
type: string
example: 'OvMeetRecordingToken=token_123456; Path=/; HttpOnly; SameSite=Strict'

View File

@ -1,6 +0,0 @@
description: >
The cookie containing the refresh token.
This cookie is used to refresh the access token when it expires.
schema:
type: string
example: 'OvMeetRefreshToken=token_123456; Path=/meet/internal-api/v1/auth; HttpOnly; SameSite=Strict'

View File

@ -1,7 +0,0 @@
name: participantIdentity
in: path
required: true
description: The identity of the participant.
schema:
type: string
example: 'Alice'

View File

@ -1,6 +1,6 @@
name: secret
in: path
required: true
description: The secret value from the room URL used to connect to the room.
description: The secret value from the room URL used to access the room.
schema:
type: string

View File

@ -1,12 +0,0 @@
name: x-participant-role
in: header
description: |
The role of the participant in the meeting. It can be one of the following values:
- `moderator`: Can manage the room and its participants.
- `speaker`: Can publish media streams to the room.
This is required to distinguish roles when multiple are present in the participant token
required: true
schema:
type: string
enum: ['moderator', 'speaker']

View File

@ -1,12 +1,7 @@
name: status
in: query
required: false
description: |
Filter recordings by their status.
You can provide multiple statuses as a comma-separated list (e.g., `status=active,failed`).
> ⚠️ **Note:** Using this filter may impact performance for large datasets.
description: Filter recordings by their status.
schema:
type: string
enum:

View File

@ -2,7 +2,8 @@ name: roomName
in: query
required: false
description: >
The name of the room.
Filter rooms by name. The search is case-insensitive and matches rooms that contain the specified text.
For example, 'room' will match 'MyRoom', 'room123', and 'Conference Room'.
schema:
type: string
example: 'room'

View File

@ -0,0 +1,10 @@
name: status
in: query
required: false
description: Filter rooms by their status.
schema:
type: string
enum:
- open
- active_meeting
- closed

View File

@ -0,0 +1,6 @@
name: sortField
in: query
required: false
description: The field by which to sort the results.
schema:
type: string

View File

@ -0,0 +1,9 @@
name: sortOrder
in: query
required: false
description: The order in which to sort the results. Use "asc" for ascending order and "desc" for descending order.
schema:
type: string
enum:
- asc
- desc

View File

@ -0,0 +1,6 @@
description: Create AI assistant activation request
required: true
content:
application/json:
schema:
$ref: '../../schemas/internal/ai-assistant-create-request.yaml'

View File

@ -1,6 +0,0 @@
description: Participant details
required: true
content:
application/json:
schema:
$ref: '../../schemas/internal/meet-participant-options.yaml'

View File

@ -0,0 +1,6 @@
description: Room member token options
required: true
content:
application/json:
schema:
$ref: '../../schemas/internal/room-member-token-options.yaml'

View File

@ -1,11 +0,0 @@
description: Room to record
required: true
content:
application/json:
schema:
type: object
properties:
roomId:
type: string
description: The unique identifier of the room to record.
example: 'room-123'

View File

@ -0,0 +1,35 @@
description: Room to record
required: true
content:
application/json:
schema:
type: object
properties:
roomId:
type: string
description: The unique identifier of the room to record.
example: 'room-123'
config:
type: object
description: |
Optional configuration to override the room's recording configuration for this specific recording.
If not provided, the recording will use the configuration defined in the room's config.
properties:
layout:
type: string
enum:
- grid
- speaker
- single-speaker
example: speaker
description: |
Defines the layout of the recording. This will override the room's default recording layout.
Options are:
- `grid`: All participants are shown in a grid layout.
- `speaker`: The active speaker is shown prominently, with other participants in smaller thumbnails.
- `single-speaker`: Only the active speaker is shown in the recording.
encoding:
description: Defines the encoding settings for the recording. This will override the room's default recording encoding.
oneOf:
- $ref: '../schemas/meet-room-config.yaml#/MeetRecordingEncodingPreset'
- $ref: '../schemas/meet-room-config.yaml#/MeetRecordingEncodingOptions'

View File

@ -11,6 +11,7 @@ content:
chat:
enabled: true
recording:
enabled: false
enabled: true
encoding: H264_720P_30
virtualBackground:
enabled: true

View File

@ -0,0 +1,17 @@
description: New room status
content:
application/json:
schema:
type: object
properties:
status:
type: string
enum:
- open
- active_meeting
- closed
example: closed
description: |
The new status of the room. Options are:
- open: The room will be open for new participants to join.
- closed: The room will be closed to new participants.

View File

@ -2,7 +2,7 @@ description: Conflict — The recording cannot be started due to resource state
content:
application/json:
schema:
$ref: '../../schemas/error.yaml'
$ref: '../schemas/error.yaml'
examples:
already_recording:
summary: Room is already being recorded

View File

@ -2,7 +2,7 @@ description: Conflict — The recording is starting or already stopped
content:
application/json:
schema:
$ref: '../../schemas/error.yaml'
$ref: '../schemas/error.yaml'
examples:
starting_recording:
summary: Recording is starting

View File

@ -0,0 +1,8 @@
description: Room not found
content:
application/json:
schema:
$ref: '../schemas/error.yaml'
example:
error: 'Room Error'
message: 'Room "room_123" has an active meeting'

View File

@ -2,7 +2,7 @@ description: Service Unavailable — The recording service is unavailable
content:
application/json:
schema:
$ref: '../../schemas/error.yaml'
$ref: '../schemas/error.yaml'
examples:
starting_timeout:
summary: Recording service timed out

View File

@ -1,4 +1,4 @@
description: Forbidden — Insufficient permissions
description: Forbidden - Insufficient Permissions
content:
application/json:
schema:

View File

@ -0,0 +1,16 @@
description: Forbidden
content:
application/json:
schema:
$ref: '../schemas/error.yaml'
examples:
forbidden_error:
summary: Forbidden Error Example
value:
error: Authorization Error
message: 'Insufficient permissions to access this resource'
recording_not_allowed:
summary: Recording Not Allowed in Room Example
value:
error: Recording Error
message: 'Recording is disabled for room room-123'

View File

@ -1,8 +0,0 @@
description: Invalid participant role provided
content:
application/json:
schema:
$ref: '../../schemas/error.yaml'
example:
error: Participant Error
message: 'No valid participant role provided'

View File

@ -1,8 +0,0 @@
description: Conflict — The participant already exists in the room
content:
application/json:
schema:
$ref: '../../schemas/error.yaml'
example:
error: 'Participant Error'
message: 'Participant "Alice" already exists in room "room_123"'

View File

@ -1,8 +0,0 @@
description: Room metadata not found
content:
application/json:
schema:
$ref: '../../schemas/error.yaml'
example:
error: 'Room Error'
message: 'Room metadata for "room_123" not found. Room "room_123" does not exist or has no recordings associated'

View File

@ -0,0 +1,5 @@
description: Successfully created or reused AI assistant activation
content:
application/json:
schema:
$ref: '../../schemas/internal/ai-assistant-create-response.yaml'

View File

@ -1,13 +0,0 @@
description: Successfully generated the participant token
# headers:
# Set-Cookie:
# $ref: '../../headers/set-cookie-participant-token.yaml'
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: >
The token to authenticate the participant.

View File

@ -1,13 +0,0 @@
description: Successfully generated the recording token
# headers:
# Set-Cookie:
# $ref: '../../headers/set-cookie-recording-token.yaml'
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: >
The token to access the recordings in the specified OpenVidu Meet room.

View File

@ -0,0 +1,10 @@
description: Successfully generated the room member token
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: >
The token to authenticate the user to access the room and its resources.

View File

@ -0,0 +1,5 @@
description: Analytics data retrieved successfully
content:
application/json:
schema:
$ref: '../../schemas/internal/meet-analytics.yaml'

View File

@ -0,0 +1,5 @@
description: Successfully retrieved captions config
content:
application/json:
schema:
$ref: '../../schemas/internal/global-captions-config.yaml'

View File

@ -2,4 +2,4 @@ description: Successfully retrieved user profile
content:
application/json:
schema:
$ref: '../../schemas/internal/user.yaml'
$ref: '../../schemas/internal/meet-user.yaml'

View File

@ -2,4 +2,4 @@ description: Successfully retrieved the room role and associated permissions
content:
application/json:
schema:
$ref: '../../schemas/internal/meet-room-role-permissions.yaml'
$ref: '../../schemas/internal/room-member-role-permissions.yaml'

View File

@ -4,7 +4,7 @@ content:
schema:
type: array
items:
$ref: '../../schemas/internal/meet-room-role-permissions.yaml'
$ref: '../../schemas/internal/room-member-role-permissions.yaml'
example:
- role: 'moderator'
permissions:
@ -17,6 +17,8 @@ content:
canUpdateOwnMetadata: true
openvidu:
canRecord: true
canRetrieveRecordings: true
canDeleteRecordings: true
canChat: true
canChangeVirtualBackground: true
- role: 'speaker'
@ -30,5 +32,7 @@ content:
canUpdateOwnMetadata: true
openvidu:
canRecord: false
canRetrieveRecordings: true
canDeleteRecordings: false
canChat: true
canChangeVirtualBackground: true

View File

@ -6,4 +6,4 @@ content:
properties:
message:
type: string
example: Participant 'Alice' kicked successfully from room 'room-123'
example: Participant 'Alice' kicked successfully from meeting in room 'room-123'

View File

@ -1,7 +1,4 @@
description: Successfully refreshed the access token
# headers:
# Set-Cookie:
# $ref: '../../headers/set-cookie-access-token.yaml'
content:
application/json:
schema:

View File

@ -1,9 +1,4 @@
description: Successfully logged in
# headers:
# Set-Cookie:
# $ref: '../../headers/set-cookie-access-token.yaml'
# Set-Cookie*:
# $ref: '../../headers/set-cookie-refresh-token.yaml'
content:
application/json:
schema:

View File

@ -1,11 +1,4 @@
description: Successfully logged out
# headers:
# Set-Cookie:
# description: >
# Clears the access and refresh token cookie.
# schema:
# type: string
# example: 'OvMeetAccessToken=; Path=/; HttpOnly; SameSite=Strict'
content:
application/json:
schema:

View File

@ -11,6 +11,7 @@ content:
roomId: 'room-123'
roomName: 'room'
status: 'complete'
layout: 'grid'
filename: 'room-123--XX445.mp4'
startDate: 1600000000000
endDate: 1600000003600
@ -25,5 +26,6 @@ content:
roomId: 'room-456'
roomName: 'room'
status: 'active'
layout: 'grid'
filename: 'room-456--QR789.mp4'
startDate: 1682500000000

View File

@ -19,6 +19,7 @@ content:
roomId: 'room-123'
roomName: 'room'
status: 'active'
layout: 'grid'
filename: 'room-123--XX445.mp4'
startDate: 1620000000000
endDate: 1620000003600
@ -29,6 +30,7 @@ content:
roomId: 'room-456'
roomName: 'room'
status: 'complete'
layout: 'grid'
filename: 'room-456--XX678.mp4'
startDate: 1625000000000
endDate: 1625000007200

View File

@ -19,8 +19,15 @@ content:
enabled: true
recording:
enabled: false
layout: grid
encoding: H264_720P_30
allowAccessTo: admin_moderator_speaker
virtualBackground:
enabled: true
e2ee:
enabled: false
captions:
enabled: true
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
status: open
@ -43,8 +50,21 @@ content:
enabled: true
recording:
enabled: false
layout: grid
encoding:
video:
width: 1920
height: 1080
framerate: 30
codec: H264_MAIN
audio:
codec: OPUS
bitrate: 128
allowAccessTo: admin_moderator_speaker
virtualBackground:
enabled: true
e2ee:
enabled: false
fields=moderatorUrl,speakerUrl:
summary: Response containing only moderator and speaker URLs

View File

@ -28,8 +28,15 @@ content:
enabled: true
recording:
enabled: false
layout: grid
encoding: H264_720P_30
allowAccessTo: admin_moderator_speaker
virtualBackground:
enabled: true
e2ee:
enabled: false
captions:
enabled: true
moderatorUrl: 'http://localhost:6080/room/room-123?secret=123456'
speakerUrl: 'http://localhost:6080/room/room-123?secret=654321'
status: open
@ -46,8 +53,21 @@ content:
enabled: false
recording:
enabled: true
layout: grid
encoding:
video:
width: 1280
height: 720
framerate: 60
codec: H264_HIGH
audio:
codec: AAC
bitrate: 192
allowAccessTo: admin_moderator_speaker
virtualBackground:
enabled: false
e2ee:
enabled: false
moderatorUrl: 'http://localhost:6080/room/room-456?secret=789012'
speakerUrl: 'http://localhost:6080/room/room-456?secret=210987'
status: open
@ -80,6 +100,8 @@ content:
enabled: false
virtualBackground:
enabled: true
e2ee:
enabled: false
- roomId: 'room-456'
roomName: 'room'
creationDate: 1620001000000
@ -91,6 +113,8 @@ content:
enabled: true
virtualBackground:
enabled: false
e2ee:
enabled: false
pagination:
isTruncated: true
nextPageToken: 'abc123'

View File

@ -0,0 +1,10 @@
description: Success response for scheduling room closure
content:
application/json:
schema:
type: object
properties:
message:
type: string
example:
message: Room 'room-123' scheduled to be closed when the meeting ends

View File

@ -1,12 +0,0 @@
description: >
All specified rooms were marked for deletion (due to active participants)
and will be removed once all participants leave.
content:
application/json:
schema:
type: object
properties:
message:
type: string
example:
message: Rooms 'room-123, room-456' marked for deletion

View File

@ -2,12 +2,13 @@ description: Successfully created the OpenVidu Meet recording
content:
application/json:
schema:
$ref: '../../schemas/meet-recording.yaml'
$ref: '../schemas/meet-recording.yaml'
example:
recordingId: 'room-123--EG_XYZ--XX445'
roomId: 'room-123'
roomName: 'room'
status: 'active'
layout: 'speaker'
filename: 'room-123--XX445.mp4'
startDate: 1600000000000
headers:

View File

@ -8,12 +8,13 @@ headers:
content:
application/json:
schema:
$ref: '../../schemas/meet-recording.yaml'
$ref: '../schemas/meet-recording.yaml'
example:
recordingId: 'room-123--EG_XYZ--XX445'
roomId: 'room-123'
roomName: 'room'
status: 'ending'
layout: 'speaker'
filename: 'room-123--XX445.mp4'
startDate: 1600000000000
details: 'End reason: StopEgress API'

View File

@ -0,0 +1,10 @@
description: Success response for updating room status
content:
application/json:
schema:
type: object
properties:
message:
type: string
example:
message: Room 'room-123' closed successfully

View File

@ -0,0 +1,37 @@
type: object
required:
# - scope
- capabilities
properties:
# scope:
# type: object
# required:
# - resourceType
# - resourceIds
# properties:
# resourceType:
# type: string
# enum: ['meeting']
# description: Scope resource type where assistant will be activated.
# example: meeting
# resourceIds:
# type: array
# minItems: 1
# items:
# type: string
# minLength: 1
# description: List of target resource ids.
# example: ['meeting_123']
capabilities:
type: array
minItems: 1
items:
type: object
required:
- name
properties:
name:
type: string
enum: ['live_captions']
description: AI capability to activate.
example: live_captions

View File

@ -0,0 +1,14 @@
type: object
required:
- id
- status
properties:
id:
type: string
description: Identifier of the assistant activation.
example: asst_123
status:
type: string
enum: ['active']
description: Current assistant activation state.
example: active

View File

@ -0,0 +1,8 @@
type: object
properties:
enabled:
type: boolean
description: Indicates whether captions are enabled in the system
example: true
required:
- enabled

View File

@ -0,0 +1,24 @@
type: object
description: Usage analytics data for OpenVidu Meet
properties:
totalRooms:
type: integer
description: Total number of rooms created
example: 42
activeRooms:
type: integer
description: Number of rooms currently with an active meeting
example: 3
totalRecordings:
type: integer
description: Total number of recordings created
example: 128
completeRecordings:
type: integer
description: Number of recordings that are complete and playable
example: 125
required:
- totalRooms
- activeRooms
- totalRecordings
- completeRecordings

Some files were not shown because too many files have changed in this diff Show More