Compare commits

..

8 Commits

Author SHA1 Message Date
lebaudantoine 0e7e5d1a4c 🔧(devx) pull the MinIO image from quay.io
The quay.io/minio/minio mirror remains publicly available, accepts the
same environment variables.
2026-09-14 19:07:01 +02:00
snyk-bot d85123d0c5 ⬆(frontend) upgrade humanize-duration from 3.33.2 to 3.34.1
Snyk has created this PR to upgrade humanize-duration from 3.33.2 to 3.34.1.

See this package in npm:
humanize-duration

See this project in Snyk:
https://app.eu.snyk.io/org/lasuite-dinum-default/project/96ea03d8-8d09-493d-86bf-363f274e129e?utm_source=github&utm_medium=referral&page=upgrade-pr
2026-09-14 15:40:56 +02:00
snyk-bot b2abf814fa ⬆️(addons) upgrade i18next from 26.3.6 to 26.4.0
Snyk has created this PR to upgrade i18next from 26.3.6 to 26.4.0.

See this package in npm:
i18next

See this project in Snyk:
https://app.eu.snyk.io/org/lasuite-dinum-default/project/af693e79-8c43-4c09-ab65-60580515c9e8?utm_source=github&utm_medium=referral&page=upgrade-pr
2026-09-14 09:10:04 +02:00
Miguel Victoria cfdf1c2f92 ✨(backend) add default video codec on apiConfig struct
Co-authored-by: David <60177543+davd-gzl@users.noreply.github.com>
2026-09-14 09:03:05 +02:00
Michel-Marie Maudet 4139f542d3 🔧(ci) pull the MinIO image from quay.io
Docker Hub now denies anonymous pulls of minio/minio (pull access
denied), which fails the test-back job for every pull request. The
quay.io/minio/minio mirror remains publicly available, accepts the
same environment variables, and the container lookup in the Configure
MinIO step still matches the image name.

thx @mmaudet
2026-09-14 07:43:02 +02:00
snyk-bot eda66640df ⬆️(frontend) upgrade posthog-js from 1.414.0 to 1.418.10
Snyk has created this PR to upgrade posthog-js from 1.414.0 to 1.418.10.

See this package in npm:
posthog-js

See this project in Snyk:
https://app.eu.snyk.io/org/lasuite-dinum-default/project/96ea03d8-8d09-493d-86bf-363f274e129e?utm_source=github&utm_medium=referral&page=upgrade-pr
2026-09-14 07:38:10 +02:00
snyk-bot 3fa05ea785 ⬆️(frontend) upgrade react-i18next from 17.0.10 to 17.0.12
Snyk has created this PR to upgrade react-i18next from 17.0.10 to 17.0.12.

See this package in npm:
react-i18next

See this project in Snyk:
https://app.eu.snyk.io/org/lasuite-dinum-default/project/96ea03d8-8d09-493d-86bf-363f274e129e?utm_source=github&utm_medium=referral&page=upgrade-pr
2026-09-14 07:03:25 +02:00
lebaudantoine 30b68052e1 ⚡️(frontend) defer loading the Crisp script until idle
Load the Crisp JavaScript module only once the frontend is idle,
instead of during the initial page load.

Keeps the critical path lighter and prevents Crisp from competing
with the app's own bootstrap for network and CPU on slow devices.
2026-09-13 00:03:55 +02:00
13 changed files with 107 additions and 57 deletions
+2 -2
View File
@@ -252,13 +252,13 @@ jobs:
- name: Start MinIO
run: |
docker pull minio/minio
docker pull quay.io/minio/minio
docker run -d --name minio \
-p 9000:9000 \
-e "MINIO_ACCESS_KEY=meet" \
-e "MINIO_SECRET_KEY=password" \
-v /data/media:/data \
minio/minio server --console-address :9001 /data
quay.io/minio/minio server --console-address :9001 /data
# Tool to wait for a service to be ready
- name: Install Dockerize
+8
View File
@@ -8,12 +8,20 @@ and this project adheres to
## [Unreleased]
### Added
- ✨(backend) make the LiveKit default video codec configurable
### Changed
- 📈(frontend) include LiveKit SIDs in the connection analytics event
- 🔇(backend) silence expected 401 warnings on /me
- 🔇(backend) silence noisy request summary info logs
- ⚡️(frontend) defer loading the Crisp script until idle
- ⬆️(frontend) upgrade react-i18next from 17.0.10 to 17.0.12
- ⬆️(frontend) upgrade posthog-js from 1.414.0 to 1.418.10
- ⬆️(addons) upgrade i18next from 26.3.6 to 26.4.0
- ⬆️(frontend) upgrade humanize-duration from 3.33.2 to 3.34.1
### Fixed
+2 -2
View File
@@ -17,7 +17,7 @@ services:
minio:
user: ${DOCKER_USER:-1000}
image: minio/minio
image: quay.io/minio/minio
environment:
- MINIO_ROOT_USER=meet
- MINIO_ROOT_PASSWORD=password
@@ -35,7 +35,7 @@ services:
- ./data/media:/data
createbuckets:
image: minio/mc
image: quay.io/minio/mc
depends_on:
minio:
condition: service_healthy
+4 -4
View File
@@ -10,7 +10,7 @@
"license": "MIT",
"dependencies": {
"core-js": "3.50.0",
"i18next": "26.3.6",
"i18next": "26.4.0",
"i18next-browser-languagedetector": "8.2.1",
"regenerator-runtime": "0.14.1"
},
@@ -9367,9 +9367,9 @@
}
},
"node_modules/i18next": {
"version": "26.3.6",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.6.tgz",
"integrity": "sha512-Bu5Z2nAXgfVyM8xvW3jk9EKRIuX37PudsrBViThNFx7CR7aaYTpP01cxNB/E4c4UUzTDiAZRstEhsRfPOL/8xA==",
"version": "26.4.0",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-26.4.0.tgz",
"integrity": "sha512-rsmK5bFqsD1AetSFSIa43wtNR4WpvvH4p0tLEsTxkC7QTrfdFm06nbQ95bh8Og4wwaCnUEcm9DVYL2cgxitiQg==",
"funding": [
{
"type": "individual",
+1 -1
View File
@@ -27,7 +27,7 @@
},
"dependencies": {
"core-js": "3.50.0",
"i18next": "26.3.6",
"i18next": "26.4.0",
"i18next-browser-languagedetector": "8.2.1",
"regenerator-runtime": "0.14.1"
},
+1
View File
@@ -71,6 +71,7 @@ def get_frontend_configuration(request):
"force_wss_protocol": settings.LIVEKIT_FORCE_WSS_PROTOCOL,
"enable_firefox_proxy_workaround": settings.LIVEKIT_ENABLE_FIREFOX_PROXY_WORKAROUND,
"default_sources": settings.LIVEKIT_DEFAULT_SOURCES,
"default_video_codec": settings.LIVEKIT_DEFAULT_VIDEO_CODEC,
},
"authenticated_users_can_edit_display_name": (
settings.AUTHENTICATED_PARTICIPANTS_CAN_EDIT_DISPLAY_NAME
@@ -0,0 +1,22 @@
"""Unit tests for the LIVEKIT_DEFAULT_VIDEO_CODEC setting value."""
import pytest
from meet.settings import VideoCodecValue
@pytest.mark.parametrize(
"raw,expected",
[("vp9", "vp9"), ("AV1", "av1"), (" h264 ", "h264")],
)
def test_video_codec_value_normalizes(raw, expected):
"""Whitespace is trimmed and the name is lowercased before it is checked."""
# environ=False keeps __new__ from resolving the value, so the instance survives.
assert VideoCodecValue(environ=False).to_python(raw) == expected
@pytest.mark.parametrize("raw", ["vp10", "", "h.264"])
def test_video_codec_value_rejects_unsupported(raw):
"""A name outside the accepted list stops the settings module loading."""
with pytest.raises(ValueError, match="Unsupported video codec"):
VideoCodecValue(environ=False).to_python(raw)
+23
View File
@@ -53,6 +53,26 @@ def get_release():
return "NA" # Default: not available
class VideoCodecValue(values.Value):
"""
A video codec name, normalized to lowercase and validated against the codecs
supported by the LiveKit client, so that a typo fails at startup instead of
silently downgrading every publisher to another codec.
"""
codecs = frozenset(("vp8", "h264", "vp9", "av1"))
def to_python(self, value):
"""Normalize the codec name and ensure it is a supported one."""
codec = super().to_python(value).strip().lower()
if codec not in self.codecs:
raise ValueError(
f"Unsupported video codec {value!r}, "
f"expected one of: {', '.join(sorted(self.codecs))}."
)
return codec
class Base(Configuration):
"""
This is the base configuration every configuration (aka environment) should inherit from. It
@@ -678,6 +698,9 @@ class Base(Configuration):
environ_prefix=None,
default=False,
)
LIVEKIT_DEFAULT_VIDEO_CODEC = VideoCodecValue(
"vp9", environ_name="LIVEKIT_DEFAULT_VIDEO_CODEC", environ_prefix=None
)
CONNECTION_TEST_ENABLED = values.BooleanValue(
environ_name="CONNECTION_TEST_ENABLED",
environ_prefix=None,
+36 -43
View File
@@ -23,18 +23,18 @@
"@timephy/rnnoise-wasm": "1.0.0",
"crisp-sdk-web": "1.1.2",
"hoofd": "1.7.3",
"humanize-duration": "3.33.2",
"humanize-duration": "3.34.1",
"i18next": "26.3.6",
"i18next-browser-languagedetector": "8.2.1",
"i18next-parser": "9.4.0",
"i18next-resources-to-backend": "1.2.3",
"livekit-client": "2.21.0",
"posthog-js": "1.414.0",
"posthog-js": "1.418.10",
"react": "18.3.1",
"react-aria": "3.50.0",
"react-aria-components": "1.19.0",
"react-dom": "18.3.1",
"react-i18next": "17.0.10",
"react-i18next": "17.0.12",
"react-stately": "3.48.0",
"use-sound": "5.0.0",
"valtio": "2.3.2",
@@ -1720,28 +1720,28 @@
"license": "MIT"
},
"node_modules/@posthog/browser-common": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@posthog/browser-common/-/browser-common-0.4.0.tgz",
"integrity": "sha512-W9DCGVks15docUMPvJ2nd8NS16Gn74bsGWuaeg31beEKFSjdW8wvnQ1ETY6WSql5pYxZb3GdJmEUZVVstKSrBQ==",
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@posthog/browser-common/-/browser-common-0.5.2.tgz",
"integrity": "sha512-8GvfEshFdeKIccuy3kpp6mDBxawQtRamMYRCwzy1r1ixLKQVLAGs3afhOf6r75yp59ZQBi5mtXQgUJ2Jz8eHuw==",
"license": "MIT",
"dependencies": {
"@posthog/core": "^1.46.8",
"@posthog/types": "^1.402.0"
"@posthog/core": "^1.48.11",
"@posthog/types": "^1.405.3"
}
},
"node_modules/@posthog/core": {
"version": "1.49.1",
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.49.1.tgz",
"integrity": "sha512-jdZh85tG56OXLH881CVwBZyiXCPPaZasfYeWwm9kVUvxC/Rb+lz7wYN9GuqSEmNPJgVnK4v8wS0bCaFc3OmVEA==",
"version": "1.53.2",
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.53.2.tgz",
"integrity": "sha512-Knx8442G2LyPVIzLvhcBX/TIdeHpZhrYrtZou3Uw8FWfbr9gQtQeOZDCog3MWcDxJ+4vAnMAAOzf5cYpc7Gxyw==",
"license": "MIT",
"dependencies": {
"@posthog/types": "^1.407.0"
"@posthog/types": "^1.411.1"
}
},
"node_modules/@posthog/types": {
"version": "1.407.1",
"resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.407.1.tgz",
"integrity": "sha512-WhbkXPC2rgylXqmxHqv70ffI3k+KxyR6s7DBIfr5NvIqHkxp6v0pk31D/jbz0DNVbzwkLjyll2pxr4FNbJiYzg==",
"version": "1.411.1",
"resolved": "https://registry.npmjs.org/@posthog/types/-/types-1.411.1.tgz",
"integrity": "sha512-Gd7tnSYctcSXup3naVlAgavvenByRao6rsSYdMgWgP35KE9jFn+rMHNRJeI5LNjJuLzMXHEVcgzAN7xcATefdw==",
"license": "MIT"
},
"node_modules/@react-aria/overlays": {
@@ -6354,11 +6354,12 @@
"integrity": "sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w=="
},
"node_modules/html-parse-stringify": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
"dependencies": {
"void-elements": "3.1.0"
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-4.0.1.tgz",
"integrity": "sha512-0zHsZJrK7S3K2aucXWL6ycoYJ/iNtIcFHC/nYQgFklPtrv5LpJctIiSCroWZWeuoXvuyFdzp6KzjJQ+OT5MfFw==",
"license": "MIT",
"funding": {
"url": "https://locize.com"
}
},
"node_modules/htmlparser2": {
@@ -6401,9 +6402,9 @@
}
},
"node_modules/humanize-duration": {
"version": "3.33.2",
"resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.33.2.tgz",
"integrity": "sha512-K7Ny/ULO1hDm2nnhvAY+SJV1skxFb61fd073SG1IWJl+D44ULrruCuTyjHKjBVVcSuTlnY99DKtgEG39CM5QOQ==",
"version": "3.34.1",
"resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.34.1.tgz",
"integrity": "sha512-YIiigjQ+O31rvcyDJPK1ptTZtvSErjBtmHy93VhbwxB/VwMG0FszKs2IB667tFxmOhNapePQQxa24luQRDkKFQ==",
"license": "Unlicense",
"funding": {
"url": "https://github.com/sponsors/EvanHahn"
@@ -9131,16 +9132,16 @@
"license": "MIT"
},
"node_modules/posthog-js": {
"version": "1.414.0",
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.414.0.tgz",
"integrity": "sha512-dtZd4asdskr8lNyltAEX6zyn48uO1pO0EMvx6AXJU65PFhu6yn2LPbKtQcyLysjcN57FJPNT9QYL6St5SBJHqw==",
"version": "1.418.10",
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.418.10.tgz",
"integrity": "sha512-XMvmmnuFoesSPjFo+wvzXkvuzYqIho8CVqxugG1Wt768offFARYNZDd1/xWfm9vk/pJTJ4RhUEHRzLpggmGx9Q==",
"license": "(Apache-2.0 AND MIT)",
"dependencies": {
"@posthog/browser-common": "^0.4.0",
"@posthog/core": "^1.46.9",
"@posthog/types": "^1.402.2",
"@posthog/browser-common": "^0.5.0",
"@posthog/core": "^1.48.8",
"@posthog/types": "^1.405.1",
"core-js": "^3.49.0",
"dompurify": "^3.4.12",
"dompurify": "^3.4.13",
"fflate": "^0.4.8",
"preact": "^10.29.3",
"query-selector-shadow-dom": "^1.0.1",
@@ -9435,13 +9436,13 @@
}
},
"node_modules/react-i18next": {
"version": "17.0.10",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.10.tgz",
"integrity": "sha512-XneHftyYA774MJkkccSkZ5oKrUpCnXIPmxio3wemqrVzCRLWiGXOMbIzObrer03fNDEnm8g8R5yYls4HcE+esg==",
"version": "17.0.12",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.12.tgz",
"integrity": "sha512-lFWPEGkxQ6RhusdUkysFBD58VHfSSzvHBzqMgN0SvfVpdQGfwtNkStTqdy08/sJd7s807qqutgx93fRpD0DJ3Q==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.29.2",
"html-parse-stringify": "^3.0.1",
"@babel/runtime": "^7.29.7",
"html-parse-stringify": "^4.0.1",
"use-sync-external-store": "^1.6.0"
},
"peerDependencies": {
@@ -11608,14 +11609,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/walk-sync": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz",
+3 -3
View File
@@ -30,18 +30,18 @@
"@timephy/rnnoise-wasm": "1.0.0",
"crisp-sdk-web": "1.1.2",
"hoofd": "1.7.3",
"humanize-duration": "3.33.2",
"humanize-duration": "3.34.1",
"i18next": "26.3.6",
"i18next-browser-languagedetector": "8.2.1",
"i18next-parser": "9.4.0",
"i18next-resources-to-backend": "1.2.3",
"livekit-client": "2.21.0",
"posthog-js": "1.414.0",
"posthog-js": "1.418.10",
"react": "18.3.1",
"react-aria": "3.50.0",
"react-aria-components": "1.19.0",
"react-dom": "18.3.1",
"react-i18next": "17.0.10",
"react-i18next": "17.0.12",
"react-stately": "3.48.0",
"use-sound": "5.0.0",
"valtio": "2.3.2",
+2 -1
View File
@@ -3,7 +3,7 @@ import { keys } from './queryKeys'
import { useQuery } from '@tanstack/react-query'
import { RecordingMode } from '@/features/recording'
import type { ApiAccessLevel } from '@/features/rooms/api/ApiRoom'
import type { Track } from 'livekit-client'
import type { Track, VideoCodec } from 'livekit-client'
type Source = Track.Source
export interface ApiConfig {
@@ -62,6 +62,7 @@ export interface ApiConfig {
force_wss_protocol: boolean
enable_firefox_proxy_workaround: boolean
default_sources: Source[]
default_video_codec: VideoCodec
}
transcription_destination?: string
max_participants_for_sound: number
@@ -107,7 +107,7 @@ export const Conference = ({
adaptiveStream: true,
dynacast: true,
publishDefaults: {
videoCodec: 'vp9',
videoCodec: apiConfig?.livekit.default_video_codec ?? 'vp9',
},
videoCaptureDefaults: {
deviceId: userConfig.videoDeviceId ?? undefined,
@@ -129,6 +129,7 @@ export const Conference = ({
userConfig.videoPublishResolution,
userConfig.audioDeviceId,
userConfig.audioOutputDeviceId,
apiConfig?.livekit.default_video_codec,
])
const room = useMemo(() => new Room(roomOptions), [roomOptions])
+1
View File
@@ -150,6 +150,7 @@ backend:
# Frontend
LIVEKIT_FORCE_WSS_PROTOCOL: True
LIVEKIT_ENABLE_FIREFOX_PROXY_WORKAROUND: True
LIVEKIT_DEFAULT_VIDEO_CODEC: vp9
FRONTEND_IDLE_DISCONNECT_WARNING_DELAY: 9000
FRONTEND_SILENCE_LIVEKIT_DEBUG: False
FRONTEND_SUPPORT: "{'id': '58ea6697-8eba-4492-bc59-ad6562585041', 'help_article_transcript': 'https://lasuite.crisp.help/fr/article/visio-transcript-1sjq43x', 'help_article_recording': 'https://lasuite.crisp.help/fr/article/visio-enregistrement-wgc8o0', 'help_article_more_tools': 'https://lasuite.crisp.help/fr/article/visio-tools-bvxj23'}"