Integrate the add-ons authentication backend into the externalviewset.
This allows third-party integrations (e.g. calendar add-ins) to
obtain a JWT for a user and use it to call the API (e.g. create a
room) via a Bearer authorization header.
Introduce a configuration flag to enable or disable the
application token exchange (service account) mechanism.
This allows activating alternative authentication backends
without requiring full application token configuration.
Required to support the upcoming add-ons authentication backend.
The external viewset expected a plural "rooms:x" scope instead of
the incorrect singular "room:x".
Update it to accept the proper scope and emit tokens accordingly.
Add a new authentication backend for add-ons, with a core service
managing session state in cache and exposing three API endpoints.
Microsoft Add-ins recommend launching authentication from the
side panel via a dialog, then returning the JWT to the parent
context using postMessage. However, due to Django and SSO security
constraints (window.opener not preserved), this approach is not
viable.
Implement a three-step authentication flow:
- `/init`: create a session, return a short-lived transit token
and CSRF token. Store session ID in a secure HttpOnly cookie.
- `/poll`: allow the add-on to poll until authentication is
complete, then consume the session and clear the cookie.
- `/exchange`: exchange the transit token for a JWT, which is
later retrieved via the `/poll` endpoint.
The add-on opens an authentication dialog, stores the transit
token in sessionStorage, and performs the exchange after login.
This approach works within iframe constraints and provides a
sufficiently secure v0 despite known limitations.
Allow controlling when the metadata collector agent is started,
enabling users to try the feature and disable it if needed.
Introduce a user-level feature flag to toggle the agent for the
initial release.
Introduce MetadataCollector and MetadataCollectorService classes to
centralize the collection and storage of user connections, VAD events,
and chat messages. This creates a structured foundation for future speaker
assignment logic based on voice activity detection. Add tests for this new
feature.
Run `uv lock --upgrade` to update transitive dependencies and
resolve the vulnerability in Pillow.
Upgrade Pillow from 12.1.1 to 12.2.0 to address the FITS GZIP
decompression bomb issue.
Tests were incorrectly mocking Twirp errors using HTTP status
codes instead of the meaningful error codes returned by the
LiveKit SDK.
Update mocks to reflect actual SDK behavior.
Replace passing the LiveKit JWT in the request body with the
Authorization header, following standard authentication practices.
Extend the LiveKit authentication backend usage across additional
endpoints.
This also raises questions about how clients should securely
retrieve LiveKit tokens, to be addressed later.
Avoid mapping all Twirp errors to generic 500 responses.
Explicitly handle the case where a participant is no longer in
the room, as this may indicate suspicious behavior or a client
state issue.
Improve error discrimination to provide more accurate responses.
Introduce toggle-hand and rename endpoints in RoomViewSet,
secured with LiveKit token authentication.
Remove direct permission for clients to update their own metadata
via LiveKit tokens to prevent spoofing (e.g. faking admin status).
Proxy participant metadata updates through the backend to enforce
proper validation and authorization.
Signed-off-by: lebaudantoine <lebaud.antoine131@gmail.com>
Resolve warnings raised in jwt/api_jwt.py:365 by ensuring test
keys meet the required security length.
Align test configuration with expected cryptographic standards.
Serialization hardening introduced a breaking change between the
frontend and backend. Adjust the Pydantic model to restore
compatibility.
Reinstate support for can_subscribe_metric, which is passed by
default from the frontend.
Email addresses are PII and should not appear in technical or
error logs.
Sanitize logging to avoid exposing sensitive user data when
invitation sending fails.
Prevent invited participants from seeing each other's email
addresses when sending room invitations.
Ensure invitations are sent with proper isolation to avoid
mass PII disclosure.
This mitigates risks of email harvesting, spam, and phishing
through the platform.
After migrating to uv-build only the module matching the project name was
included in sdist/wheel packages. Without a src layout additional modules
need to be tracked manually to ship them in built packages.
Make SESSION_ENGINE configurable through environment variable,
following the same values.Value() pattern already used for
SESSION_COOKIE_AGE. This enables OIDC backchannel-logout by
allowing users to set SESSION_ENGINE to db backend.
Closes#1037
Sanitize error handling to prevent leaking internal details when
invalid or malicious requests are sent to the API.
Return generic error responses to reduce the risk of information
disclosure during probing attempts.
The dot before (?P<extension>...) was not escaped and matched any
character instead of a literal period.
Escape it to align with MEDIA_STORAGE_URL_PATTERN, which correctly
uses \. for the file extension separator.
Update the response message to explicitly state that certain
notifications are ignored on purpose, avoiding confusion
during debugging or log inspection.
With the introduction of background file uploads, a misconfigured
MinIO webhook could trigger the storage hook endpoint for unrelated
files.
While the dev setup now filters events via the MinIO lifecycle
configuration, add a safeguard at the application level.
Enforce a stricter filepath regex when parsing storage hook events
and ignore files outside the recording output directory.
Return a clean 200 response to acknowledge the webhook while
avoiding unnecessary processing.
Avoid duplicating patterns that match the same logical unit by
sharing common parts between the two regexes.
This logical factorization improves maintainability and ensures
consistent parsing behavior across S3 event handlers.
Initially I avoided coupling the recording path regex with the
setting that provides the Django static URL. However the new
file viewset already relies on it, and Drive does as well.
For consistency, update the recording regex to use the same
STATIC_URL-based approach.
While the coupling may not feel ideal, having two different
regex strategies for similar file paths would be worse.
Combine the regex used in Drive with the one from the recording
feature and centralize them in the enums module.
Although the module name suggests only enums, it also hosts
shared constants used across the codebase.
Add FILE_UPLOAD_ENABLED setting (default to False, to avoid
a breaking change). Also adds a max_count_by_user sub setting
to restrict the number of uploaded files per user.
Authenticate the application secret before checking whether the
application is inactive.
This avoids revealing the inactive status of an application when
an incorrect secret is provided, preventing an authentication
state oracle and client_id enumeration.
Currently the inactive status is revealed before verifying the
secret, creating an authentication state oracle.
Introduce a failing test to capture the issue before
applying the fix.
Add minimal admin support to allow administrators to mark an
application account as inactive if it becomes rogue or compromised.
This capability was missing when the application concept was
initially introduced in the backend.
Most models in the project use `is_active` rather than `active`.
The Application model was not aligned with this convention.
Rename the field and add a migration to standardize the naming.
Update related tests accordingly.
This change should not introduce breaking changes for external
applications.
Remove the user-provided filename while preserving the extension,
and switch to the format `uuid.extension`.
This is more natural than the previous `uuid/.extension` format
and avoids confusion.
Update related tests accordingly.
Migrate main meet app to use UV for dependancy management.
Also optimized the backend image build sequence for faster rebuilds
when dependencies don't change.
Also removed compiled django translations files are they are done in the build
process now.
Changes inspired by drive repo.
Making the status read-only improved security and enforced least
privilege, but in production some recordings could not be properly
stopped, leaving them in an active state.
Introduce an admin action to allow support staff to mark recordings
as "failed to stop" or update their status when necessary.
Throttle the request-entry endpoint for authenticated users also
to guard against accidental hammering from buggy clients.
Authenticated users are throttled via RequestEntryUserRateThrottle.
Anonymous users are throttled using the lobby participant cookie
through RequestEntryAnonRateThrottle.
use the lobby participant cookie ID as the throttle cache key
rather than the client IP address.
This avoids penalising multiple users behind the same NAT or proxy
and aligns throttling with how LobbyService identifies participants.
This bug was spotted in production where users from ministries behind
NAT was blocked by throttling while using visio.
If no cookie is present yet, skip throttling for the request. The
cookie will be set on the first response and throttling will apply
from subsequent requests.
This throttle is intended to protect against accidental hammering
from buggy clients, not as a security control against DoS attacks.
This is not a security measure, we should use a WAF.