mirror of
https://github.com/suitenumerique/meet.git
synced 2026-11-13 13:59:19 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 538aba2477 |
+14
-14
@@ -87,7 +87,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -117,11 +117,11 @@ jobs:
|
||||
timeout 30 sh -c 'until docker exec garage /garage health; do sleep 1; done'
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
|
||||
with:
|
||||
python-version: "3.13"
|
||||
python-version: "3.15"
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
||||
uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
||||
- name: Install the dependencies
|
||||
run: uv sync --locked --all-extras
|
||||
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -170,12 +170,12 @@ jobs:
|
||||
sudo apt-get install -y ffmpeg
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
||||
uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
|
||||
with:
|
||||
python-version: "3.13"
|
||||
python-version: "3.15"
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
||||
uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
||||
|
||||
- name: Install the project
|
||||
run: uv sync --locked --all-extras
|
||||
@@ -189,7 +189,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -208,14 +208,14 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
|
||||
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
||||
with:
|
||||
node-version: "24.22.1"
|
||||
node-version: "26.13.0"
|
||||
|
||||
- name: Install dependencies
|
||||
run: cd src/frontend/ && npm ci --ignore-scripts
|
||||
@@ -232,7 +232,7 @@ jobs:
|
||||
working-directory: src/sdk/library
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -255,7 +255,7 @@ jobs:
|
||||
working-directory: src/sdk/library
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
@@ -37,8 +37,6 @@ and this project adheres to
|
||||
- 🔒️(agents) upgrade python to 3.14.10 to fix CVE-2026-109518
|
||||
- 🔒️(docker) upgrade musl-utils to 1.2.6-r3 to fix CVE-2026-107891
|
||||
- ♿️(frontend) close the invite dialog with the Escape key #1916
|
||||
- 🔒️(docker) move frontend to nginx/nginx-unprivileged image
|
||||
- 🐛(frontend) accept meeting links with query params in join dialog
|
||||
|
||||
## [1.37.0] - 2026-11-01
|
||||
|
||||
|
||||
@@ -58,13 +58,19 @@ RUN npx webpack --mode production
|
||||
|
||||
|
||||
# ---- Front-end image ----
|
||||
FROM nginx/nginx-unprivileged:1.30.6-alpine3.24 AS frontend-production
|
||||
FROM nginxinc/nginx-unprivileged:1.30.6-alpine3.24 AS frontend-production
|
||||
|
||||
USER root
|
||||
RUN apk del curl && \
|
||||
RUN apk upgrade --no-cache libexpat && \
|
||||
apk add --no-cache --upgrade 'pcre2>=10.49-r0' 'tiff>=4.7.2-r0' \
|
||||
'libx11>=1.8.14-r0' 'ca-certificates>=20261020-r0' \
|
||||
'brotli-libs>=1.2.1-r0' 'musl-utils>=1.2.6-r3' && \
|
||||
apk del curl && \
|
||||
rm -f /usr/share/nginx/html/50x.html
|
||||
USER nginx
|
||||
|
||||
USER nginx
|
||||
|
||||
# Un-privileged user running the application
|
||||
ARG DOCKER_USER
|
||||
USER ${DOCKER_USER}
|
||||
|
||||
@@ -47,10 +47,14 @@ ENV VITE_MEDIA_BASE_URL=${VITE_MEDIA_BASE_URL}
|
||||
RUN npm run build
|
||||
|
||||
# ---- Front-end image ----
|
||||
FROM nginx/nginx-unprivileged:1.30.6-alpine3.24 AS frontend-production
|
||||
FROM nginxinc/nginx-unprivileged:1.30.6-alpine3.24 AS frontend-production
|
||||
|
||||
USER root
|
||||
RUN apk del curl && \
|
||||
RUN apk upgrade --no-cache libexpat && \
|
||||
apk add --no-cache --upgrade 'pcre2>=10.49-r0' 'tiff>=4.7.2-r0' \
|
||||
'libx11>=1.8.14-r0' 'ca-certificates>=20261020-r0' \
|
||||
'brotli-libs>=1.2.1-r0' 'musl-utils>=1.2.6-r3' && \
|
||||
apk del curl && \
|
||||
rm -f /usr/share/nginx/html/50x.html
|
||||
USER nginx
|
||||
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Field, Ul, H, P, Form, Dialog } from '@/primitives'
|
||||
import { navigateTo } from '@/navigation/navigateTo'
|
||||
import { extractRoomId } from '@/features/rooms'
|
||||
import { isRoomValid } from '@/features/rooms'
|
||||
|
||||
export const JoinMeetingDialog = () => {
|
||||
const { t } = useTranslation('home')
|
||||
|
||||
const handleSubmit = (data: { roomId?: FormDataEntryValue }) => {
|
||||
const extracted = extractRoomId(data.roomId as string)
|
||||
if (!extracted) return
|
||||
navigateTo('room', `${extracted.roomId}${extracted.suffix}`)
|
||||
const roomId = (data.roomId as string)
|
||||
.trim()
|
||||
.replace(`${window.location.origin}/`, '')
|
||||
navigateTo('room', roomId)
|
||||
}
|
||||
|
||||
const validateRoomId = (value: string) => {
|
||||
const trimmed = value.trim()
|
||||
if (!trimmed) return null
|
||||
return !extractRoomId(trimmed) ? (
|
||||
return !isRoomValid(trimmed) ? (
|
||||
<>
|
||||
<p>{t('joinInputError')}</p>
|
||||
<Ul>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
export {
|
||||
roomIdPattern,
|
||||
isRoomValid,
|
||||
extractRoomId,
|
||||
flexibleRoomIdPattern,
|
||||
} from './utils/isRoomValid'
|
||||
export { generateRoomId } from './utils/generateRoomId'
|
||||
|
||||
@@ -1,45 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { extractRoomId, normalizeRoomId } from './isRoomValid'
|
||||
|
||||
describe('extractRoomId', () => {
|
||||
const origin = 'https://meet.example.com'
|
||||
|
||||
const plain = { roomId: 'abc-defg-hij', suffix: '' }
|
||||
|
||||
it('accepts a bare room id', () => {
|
||||
expect(extractRoomId('abc-defg-hij', origin)).toEqual(plain)
|
||||
expect(extractRoomId(' abc-defg-hij ', origin)).toEqual(plain)
|
||||
})
|
||||
|
||||
it('accepts a meeting URL on this origin', () => {
|
||||
expect(extractRoomId(`${origin}/abc-defg-hij`, origin)).toEqual(plain)
|
||||
expect(extractRoomId(`${origin}/abc-defg-hij/`, origin)).toEqual(plain)
|
||||
})
|
||||
|
||||
it('keeps query strings and fragments in the suffix', () => {
|
||||
expect(
|
||||
extractRoomId(`${origin}/abc-defg-hij?from=outlook-addin`, origin)
|
||||
).toEqual({ roomId: 'abc-defg-hij', suffix: '?from=outlook-addin' })
|
||||
expect(
|
||||
extractRoomId(
|
||||
`${origin}/abc-defg-hij/?utm_source=mail&utm_medium=email#x`,
|
||||
origin
|
||||
)
|
||||
).toEqual({
|
||||
roomId: 'abc-defg-hij',
|
||||
suffix: '?utm_source=mail&utm_medium=email#x',
|
||||
})
|
||||
})
|
||||
|
||||
it('rejects other origins and invalid ids', () => {
|
||||
expect(
|
||||
extractRoomId('https://evil.example/abc-defg-hij', origin)
|
||||
).toBeNull()
|
||||
expect(extractRoomId(`${origin}/not-a-room`, origin)).toBeNull()
|
||||
expect(extractRoomId(`${origin}/abc-defg-hij/extra`, origin)).toBeNull()
|
||||
expect(extractRoomId('abc-defg-hij?from=x', origin)).toBeNull()
|
||||
})
|
||||
})
|
||||
import { normalizeRoomId } from './isRoomValid'
|
||||
|
||||
describe('normalizeRoomId', () => {
|
||||
it('lowercases and re-inserts the hyphens of a ten-letter id', () => {
|
||||
|
||||
@@ -10,28 +10,6 @@ export const isRoomValid = (roomIdOrUrl: string) =>
|
||||
roomRegex.test(roomIdOrUrl) ||
|
||||
new RegExp(`^${window.location.origin}/${roomIdPattern}$`).test(roomIdOrUrl)
|
||||
|
||||
export const extractRoomId = (
|
||||
input: string,
|
||||
origin: string = window.location.origin
|
||||
): { roomId: string; suffix: string } | null => {
|
||||
const value = input.trim()
|
||||
if (roomRegex.test(value)) return { roomId: value, suffix: '' }
|
||||
|
||||
let url: URL
|
||||
try {
|
||||
url = new URL(value)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
if (url.origin !== origin) return null
|
||||
|
||||
const path = url.pathname.slice(1)
|
||||
const roomId = path.endsWith('/') ? path.slice(0, -1) : path
|
||||
return roomRegex.test(roomId)
|
||||
? { roomId, suffix: `${url.search}${url.hash}` }
|
||||
: null
|
||||
}
|
||||
|
||||
export const normalizeRoomId = (roomId: string) => {
|
||||
const cleanId = roomId.toLowerCase().replace(/-/g, '')
|
||||
if (cleanId.length === 10) {
|
||||
|
||||
Reference in New Issue
Block a user