diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 5d1bf6a9..b5cf8765 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -67,7 +67,7 @@ jobs: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=sha,format=short,event=branch - type=semver,pattern={{version}} + type=semver,pattern=v{{version}} type=raw,value=latest-ci,enable={{is_default_branch}} type=raw,value=latest-ci_${{steps.current-time.outputs.unix_time}},enable={{is_default_branch}} diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index fb9ebfe9..076c65b8 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -75,7 +75,6 @@ "Not registered yet? <2>Create an account": "Not registered yet? <2>Create an account", "Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}": "Other users are trying to join this call from incompatible versions. These users should ensure that they have refreshed their browsers:<1>{userLis}", "Password": "Password", - "Password (if none, E2EE is disabled)": "Password (if none, E2EE is disabled)", "Passwords must match": "Passwords must match", "Profile": "Profile", "Recaptcha dismissed": "Recaptcha dismissed", @@ -106,6 +105,7 @@ "Thanks, we received your feedback!": "Thanks, we received your feedback!", "Thanks!": "Thanks!", "This call already exists, would you like to join?": "This call already exists, would you like to join?", + "This call is not end-to-end encrypted.": "This call is not end-to-end encrypted.", "This site is protected by ReCAPTCHA and the Google <2>Privacy Policy and <6>Terms of Service apply.<9>By clicking \"Register\", you agree to our <12>End User Licensing Agreement (EULA)": "This site is protected by ReCAPTCHA and the Google <2>Privacy Policy and <6>Terms of Service apply.<9>By clicking \"Register\", you agree to our <12>End User Licensing Agreement (EULA)", "Turn off camera": "Turn off camera", "Turn on camera": "Turn on camera", diff --git a/src/E2EEBanner.tsx b/src/E2EEBanner.tsx index 957813e3..774f3582 100644 --- a/src/E2EEBanner.tsx +++ b/src/E2EEBanner.tsx @@ -19,8 +19,12 @@ import { Trans } from "react-i18next"; import { Banner } from "./Banner"; import styles from "./E2EEBanner.module.css"; import { ReactComponent as LockOffIcon } from "./icons/LockOff.svg"; +import { useEnableE2EE } from "./settings/useSetting"; export const E2EEBanner = () => { + const [e2eeEnabled] = useEnableE2EE(); + if (e2eeEnabled) return null; + return (
diff --git a/src/E2EELock.tsx b/src/E2EELock.tsx index d032b036..9a9a55e9 100644 --- a/src/E2EELock.tsx +++ b/src/E2EELock.tsx @@ -26,10 +26,7 @@ import { TooltipTrigger } from "./Tooltip"; export const E2EELock = () => { const { t } = useTranslation(); const tooltip = useCallback( - () => - t( - "Element Call is temporarily not end-to-end encrypted while we test scalability." - ), + () => t("This call is not end-to-end encrypted."), [t] ); diff --git a/src/UrlParams.ts b/src/UrlParams.ts index 700c8154..e6f0cd05 100644 --- a/src/UrlParams.ts +++ b/src/UrlParams.ts @@ -19,6 +19,8 @@ import { useLocation } from "react-router-dom"; import { Config } from "./config/Config"; +export const PASSWORD_STRING = "password="; + interface UrlParams { roomAlias: string | null; roomId: string | null; @@ -86,6 +88,10 @@ interface UrlParams { * user's homeserver doesn't provide any. */ allowIceFallback: boolean; + /** + * E2EE password + */ + password: string | null; } /** @@ -102,9 +108,12 @@ export const getUrlParams = ( pathname = window.location.pathname, hash = window.location.hash ): UrlParams => { + // This is legacy code - we're moving away from using aliases let roomAlias: string | null = null; if (!ignoreRoomAlias) { - if (hash === "") { + // Here we handle the beginning of the alias and make sure it starts with a + // "#" + if (hash === "" || hash.startsWith("#?")) { roomAlias = pathname.substring(1); // Strip the "/" // Delete "/room/", if present @@ -119,17 +128,17 @@ export const getUrlParams = ( roomAlias = hash; } - // Add server part, if not present - if (!roomAlias.includes(":")) { - roomAlias = `${roomAlias}:${Config.defaultServerName()}`; - } - // Delete "?" and what comes afterwards roomAlias = roomAlias.split("?")[0]; - // Make roomAlias undefined, if empty if (roomAlias.length <= 1) { + // Make roomAlias is null, if it only is a "#" roomAlias = null; + } else { + // Add server part, if not present + if (!roomAlias.includes(":")) { + roomAlias = `${roomAlias}:${Config.defaultServerName()}`; + } } } @@ -164,6 +173,7 @@ export const getUrlParams = ( return { roomAlias, roomId, + password: getParam("password"), viaServers: getAllParams("via"), isEmbedded: hasParam("embed"), preload: hasParam("preload"), diff --git a/src/analytics/PosthogAnalytics.ts b/src/analytics/PosthogAnalytics.ts index 0ca23fb3..9d4f3f5c 100644 --- a/src/analytics/PosthogAnalytics.ts +++ b/src/analytics/PosthogAnalytics.ts @@ -20,7 +20,7 @@ import { MatrixClient } from "matrix-js-sdk"; import { Buffer } from "buffer"; import { widget } from "../widget"; -import { getSetting, setSetting, settingsBus } from "../settings/useSetting"; +import { getSetting, setSetting, getSettingKey } from "../settings/useSetting"; import { CallEndedTracker, CallStartedTracker, @@ -34,6 +34,7 @@ import { } from "./PosthogEvents"; import { Config } from "../config/Config"; import { getUrlParams } from "../UrlParams"; +import { localStorageBus } from "../useLocalStorage"; /* Posthog analytics tracking. * @@ -413,7 +414,7 @@ export class PosthogAnalytics { // * When the user changes their preferences on this device // Note that for new accounts, pseudonymousAnalyticsOptIn won't be set, so updateAnonymityFromSettings // won't be called (i.e. this.anonymity will be left as the default, until the setting changes) - settingsBus.on("opt-in-analytics", (optInAnalytics) => { + localStorageBus.on(getSettingKey("opt-in-analytics"), (optInAnalytics) => { this.updateAnonymityAndIdentifyUser(optInAnalytics); }); } diff --git a/src/e2ee/sharedKeyManagement.ts b/src/e2ee/sharedKeyManagement.ts new file mode 100644 index 00000000..3af56d6f --- /dev/null +++ b/src/e2ee/sharedKeyManagement.ts @@ -0,0 +1,81 @@ +/* +Copyright 2023 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { useEffect, useMemo } from "react"; + +import { useEnableE2EE } from "../settings/useSetting"; +import { useLocalStorage } from "../useLocalStorage"; +import { useClient } from "../ClientContext"; +import { PASSWORD_STRING, useUrlParams } from "../UrlParams"; + +export const getRoomSharedKeyLocalStorageKey = (roomId: string): string => + `room-shared-key-${roomId}`; + +export const useInternalRoomSharedKey = ( + roomId: string +): [string | null, (value: string) => void] => { + const key = useMemo(() => getRoomSharedKeyLocalStorageKey(roomId), [roomId]); + const [e2eeEnabled] = useEnableE2EE(); + const [roomSharedKey, setRoomSharedKey] = useLocalStorage(key); + + return [e2eeEnabled ? roomSharedKey : null, setRoomSharedKey]; +}; + +export const useRoomSharedKey = (roomId: string): string | null => { + return useInternalRoomSharedKey(roomId)[0]; +}; + +export const useManageRoomSharedKey = (roomId: string): string | null => { + const { password } = useUrlParams(); + const [e2eeSharedKey, setE2EESharedKey] = useInternalRoomSharedKey(roomId); + + useEffect(() => { + if (!password) return; + if (password === "") return; + if (password === e2eeSharedKey) return; + + setE2EESharedKey(password); + }, [password, e2eeSharedKey, setE2EESharedKey]); + + useEffect(() => { + const hash = location.hash; + + if (!hash.includes("?")) return; + if (!hash.includes(PASSWORD_STRING)) return; + if (password !== e2eeSharedKey) return; + + const [hashStart, passwordStart] = hash.split(PASSWORD_STRING); + const hashEnd = passwordStart.split("&")[1]; + + location.replace((hashStart ?? "") + (hashEnd ?? "")); + }, [password, e2eeSharedKey]); + + return e2eeSharedKey; +}; + +export const useIsRoomE2EE = (roomId: string): boolean | null => { + const client = useClient(); + const room = useMemo( + () => client.client?.getRoom(roomId) ?? null, + [roomId, client.client] + ); + const isE2EE = useMemo( + () => (room ? !room?.getCanonicalAlias() : null), + [room] + ); + + return isE2EE; +}; diff --git a/src/home/CallList.tsx b/src/home/CallList.tsx index c3d5a6ae..1e36360e 100644 --- a/src/home/CallList.tsx +++ b/src/home/CallList.tsx @@ -23,8 +23,9 @@ import { Facepile } from "../Facepile"; import { Avatar, Size } from "../Avatar"; import styles from "./CallList.module.css"; import { getRoomUrl } from "../matrix-utils"; -import { Body, Caption } from "../typography/Typography"; +import { Body } from "../typography/Typography"; import { GroupCallRoom } from "./useGroupCallRooms"; +import { useRoomSharedKey } from "../e2ee/sharedKeyManagement"; interface CallListProps { rooms: GroupCallRoom[]; @@ -35,13 +36,13 @@ export function CallList({ rooms, client, disableFacepile }: CallListProps) { return ( <>
- {rooms.map(({ roomAlias, roomName, avatarUrl, participants }) => ( + {rooms.map(({ room, roomAlias, roomName, avatarUrl, participants }) => ( @@ -59,7 +60,7 @@ export function CallList({ rooms, client, disableFacepile }: CallListProps) { interface CallTileProps { name: string; avatarUrl: string; - roomAlias: string; + roomId: string; participants: RoomMember[]; client: MatrixClient; disableFacepile?: boolean; @@ -67,17 +68,16 @@ interface CallTileProps { function CallTile({ name, avatarUrl, - roomAlias, + roomId, participants, client, disableFacepile, }: CallTileProps) { + const roomSharedKey = useRoomSharedKey(roomId); + return (
- + {name} - {getRoomUrl(roomAlias)} {participants && !disableFacepile && (
); diff --git a/src/home/RegisteredView.tsx b/src/home/RegisteredView.tsx index 76da921d..42aba9e8 100644 --- a/src/home/RegisteredView.tsx +++ b/src/home/RegisteredView.tsx @@ -17,6 +17,7 @@ limitations under the License. import { useState, useCallback, FormEvent, FormEventHandler } from "react"; import { useHistory } from "react-router-dom"; import { MatrixClient } from "matrix-js-sdk/src/client"; +import { randomString } from "matrix-js-sdk/src/randomstring"; import { useTranslation } from "react-i18next"; import { @@ -37,9 +38,11 @@ import { JoinExistingCallModal } from "./JoinExistingCallModal"; import { Caption, Title } from "../typography/Typography"; import { Form } from "../form/Form"; import { CallType, CallTypeDropdown } from "./CallTypeDropdown"; -import { useOptInAnalytics } from "../settings/useSetting"; +import { useEnableE2EE, useOptInAnalytics } from "../settings/useSetting"; import { AnalyticsNotice } from "../analytics/AnalyticsNotice"; import { E2EEBanner } from "../E2EEBanner"; +import { setLocalStorageItem } from "../useLocalStorage"; +import { getRoomSharedKeyLocalStorageKey } from "../e2ee/sharedKeyManagement"; interface Props { client: MatrixClient; @@ -54,6 +57,7 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) { const history = useHistory(); const { t } = useTranslation(); const { modalState, modalProps } = useModalTriggerState(); + const [e2eeEnabled] = useEnableE2EE(); const onSubmit: FormEventHandler = useCallback( (e: FormEvent) => { @@ -70,16 +74,23 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) { setError(undefined); setLoading(true); - const [roomAlias] = await createRoom(client, roomName, ptt); + const roomId = ( + await createRoom(client, roomName, ptt, e2eeEnabled ?? false) + )[1]; - if (roomAlias) { - history.push(`/${roomAlias.substring(1).split(":")[0]}`); + if (e2eeEnabled) { + setLocalStorageItem( + getRoomSharedKeyLocalStorageKey(roomId), + randomString(32) + ); } + + history.push(`/room/#?roomId=${roomId}`); } submit().catch((error) => { if (error.errcode === "M_ROOM_IN_USE") { - setExistingRoomId(roomAliasLocalpartFromRoomName(roomName)); + setExistingAlias(roomAliasLocalpartFromRoomName(roomName)); setLoading(false); setError(undefined); modalState.open(); @@ -90,15 +101,15 @@ export function RegisteredView({ client, isPasswordlessUser }: Props) { } }); }, - [client, history, modalState, callType] + [client, history, modalState, callType, e2eeEnabled] ); const recentRooms = useGroupCallRooms(client); - const [existingRoomId, setExistingRoomId] = useState(); + const [existingAlias, setExistingAlias] = useState(); const onJoinExistingRoom = useCallback(() => { - history.push(`/${existingRoomId}`); - }, [history, existingRoomId]); + history.push(`/${existingAlias}`); + }, [history, existingAlias]); const callNameLabel = callType === CallType.Video diff --git a/src/home/UnauthenticatedView.tsx b/src/home/UnauthenticatedView.tsx index f479901f..721c56d1 100644 --- a/src/home/UnauthenticatedView.tsx +++ b/src/home/UnauthenticatedView.tsx @@ -40,9 +40,11 @@ import styles from "./UnauthenticatedView.module.css"; import commonStyles from "./common.module.css"; import { generateRandomName } from "../auth/generateRandomName"; import { AnalyticsNotice } from "../analytics/AnalyticsNotice"; -import { useOptInAnalytics } from "../settings/useSetting"; +import { useEnableE2EE, useOptInAnalytics } from "../settings/useSetting"; import { Config } from "../config/Config"; import { E2EEBanner } from "../E2EEBanner"; +import { getRoomSharedKeyLocalStorageKey } from "../e2ee/sharedKeyManagement"; +import { setLocalStorageItem } from "../useLocalStorage"; export const UnauthenticatedView: FC = () => { const { setClient } = useClient(); @@ -58,6 +60,8 @@ export const UnauthenticatedView: FC = () => { const history = useHistory(); const { t } = useTranslation(); + const [e2eeEnabled] = useEnableE2EE(); + const onSubmit: FormEventHandler = useCallback( (e) => { e.preventDefault(); @@ -79,9 +83,18 @@ export const UnauthenticatedView: FC = () => { true ); - let roomAlias: string; + let roomId: string; try { - [roomAlias] = await createRoom(client, roomName, ptt); + roomId = ( + await createRoom(client, roomName, ptt, e2eeEnabled ?? false) + )[1]; + + if (e2eeEnabled) { + setLocalStorageItem( + getRoomSharedKeyLocalStorageKey(roomId), + randomString(32) + ); + } } catch (error) { if (!setClient) { throw error; @@ -110,7 +123,7 @@ export const UnauthenticatedView: FC = () => { } setClient({ client, session }); - history.push(`/${roomAlias.substring(1).split(":")[0]}`); + history.push(`/room/#?roomId=${roomId}`); } submit().catch((error) => { @@ -120,7 +133,16 @@ export const UnauthenticatedView: FC = () => { reset(); }); }, - [register, reset, execute, history, callType, modalState, setClient] + [ + register, + reset, + execute, + history, + callType, + modalState, + setClient, + e2eeEnabled, + ] ); const callNameLabel = diff --git a/src/home/useGroupCallRooms.ts b/src/home/useGroupCallRooms.ts index 0f5d8ef9..58135b04 100644 --- a/src/home/useGroupCallRooms.ts +++ b/src/home/useGroupCallRooms.ts @@ -89,8 +89,7 @@ export function useGroupCallRooms(client: MatrixClient): GroupCallRoom[] { const groupCalls = client.groupCallEventHandler.groupCalls.values(); const rooms = Array.from(groupCalls).map((groupCall) => groupCall.room); - const filteredRooms = rooms.filter((r) => r.getCanonicalAlias()); // We don't display rooms without an alias - const sortedRooms = sortRooms(client, filteredRooms); + const sortedRooms = sortRooms(client, rooms); const items = sortedRooms.map((room) => { const groupCall = client.getGroupCallForRoom(room.roomId)!; diff --git a/src/matrix-utils.ts b/src/matrix-utils.ts index 73ab4151..aed343a5 100644 --- a/src/matrix-utils.ts +++ b/src/matrix-utils.ts @@ -32,7 +32,7 @@ import { import type { MatrixClient } from "matrix-js-sdk/src/client"; import type { Room } from "matrix-js-sdk/src/models/room"; import IndexedDBWorker from "./IndexedDBWorker?worker"; -import { getUrlParams } from "./UrlParams"; +import { getUrlParams, PASSWORD_STRING } from "./UrlParams"; import { loadOlm } from "./olm"; import { Config } from "./config/Config"; @@ -272,14 +272,15 @@ export function isLocalRoomId(roomId: string, client: MatrixClient): boolean { export async function createRoom( client: MatrixClient, name: string, - ptt: boolean + ptt: boolean, + e2ee: boolean ): Promise<[string, string]> { logger.log(`Creating room for group call`); const createPromise = client.createRoom({ visibility: Visibility.Private, preset: Preset.PublicChat, name, - room_alias_name: roomAliasLocalpartFromRoomName(name), + room_alias_name: e2ee ? undefined : roomAliasLocalpartFromRoomName(name), power_level_content_override: { invite: 100, kick: 100, @@ -341,15 +342,16 @@ export async function createRoom( return [fullAliasFromRoomName(name, client), result.room_id]; } -// Returns a URL to that will load Element Call with the given room -export function getRoomUrl(roomIdOrAlias: string): string { - if (roomIdOrAlias.startsWith("#")) { - return `${window.location.protocol}//${window.location.host}/${ - roomIdOrAlias.substring(1).split(":")[0] - }`; - } else { - return `${window.location.protocol}//${window.location.host}/room?roomId=${roomIdOrAlias}`; - } +/** + * Returns a URL to that will load Element Call with the given room + * @param roomId of the room + * @param password + * @returns + */ +export function getRoomUrl(roomId: string, password?: string): string { + return `${window.location.protocol}//${ + window.location.host + }/room/#?roomId=${roomId}${password ? "&" + PASSWORD_STRING + password : ""}`; } export function getAvatarUrl( diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index 9a91bfcf..eaf334ce 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -31,7 +31,6 @@ import { MatrixInfo } from "./VideoPreview"; import { CallEndedView } from "./CallEndedView"; import { PosthogAnalytics } from "../analytics/PosthogAnalytics"; import { useProfile } from "../profile/useProfile"; -import { E2EEConfig } from "../livekit/useLiveKit"; import { findDeviceByName } from "../media-utils"; //import { OpenIDLoader } from "../livekit/OpenIDLoader"; import { ActiveCall } from "./InCallView"; @@ -41,6 +40,11 @@ import { LivekitFocus } from "../livekit/LivekitFocus"; import { useMatrixRTCSessionMemberships } from "../useMatrixRTCSessionMemberships"; import { enterRTCSession, leaveRTCSession } from "../rtcSessionHelpers"; import { useMatrixRTCSessionJoinState } from "../useMatrixRTCSessionJoinState"; +import { + useManageRoomSharedKey, + useIsRoomE2EE, +} from "../e2ee/sharedKeyManagement"; +import { useEnableE2EE } from "../settings/useSetting"; declare global { interface Window { @@ -78,6 +82,9 @@ export function GroupCallView({ const memberships = useMatrixRTCSessionMemberships(rtcSession); const isJoined = useMatrixRTCSessionJoinState(rtcSession); + const e2eeSharedKey = useManageRoomSharedKey(groupCall.room.roomId); + const isRoomE2EE = useIsRoomE2EE(groupCall.room.roomId); + const { t } = useTranslation(); useEffect(() => { @@ -243,8 +250,11 @@ export function GroupCallView({ } }, [isJoined, rtcSession]); - const [e2eeConfig, setE2EEConfig] = useState( - undefined + const [e2eeEnabled] = useEnableE2EE(); + + const e2eeConfig = useMemo( + () => (e2eeSharedKey ? { sharedKey: e2eeSharedKey } : undefined), + [e2eeSharedKey] ); const onReconnect = useCallback(() => { @@ -266,6 +276,22 @@ export function GroupCallView({ return ; } + if (e2eeEnabled && isRoomE2EE && !e2eeSharedKey) { + return ( + + ); + } + + if (!e2eeEnabled && isRoomE2EE) { + return ; + } + if (isJoined) { return ( /* { - setE2EEConfig(e2eeConfig); - enterRTCSession(rtcSession); - }} + onEnter={() => enter()} isEmbedded={isEmbedded} hideHeader={hideHeader} /> diff --git a/src/room/InCallView.tsx b/src/room/InCallView.tsx index 556ec4c4..e8e6c71c 100644 --- a/src/room/InCallView.tsx +++ b/src/room/InCallView.tsx @@ -78,6 +78,7 @@ import { useEventEmitterThree } from "../useEvents"; import { useWakeLock } from "../useWakeLock"; import { useMergedRefs } from "../useMergedRefs"; import { MuteStates } from "./MuteStates"; +import { useIsRoomE2EE } from "../e2ee/sharedKeyManagement"; const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {}); // There is currently a bug in Safari our our code with cloning and sending MediaStreams @@ -133,6 +134,8 @@ export function InCallView({ usePreventScroll(); useWakeLock(); + const isRoomE2EE = useIsRoomE2EE(rtcSession.room.roomId); + const containerRef1 = useRef(null); const [containerRef2, bounds] = useMeasure({ polyfill: ResizeObserver }); const boundsValid = bounds.height > 0; @@ -408,7 +411,7 @@ export function InCallView({
- + {!isRoomE2EE && } @@ -445,12 +448,7 @@ export function InCallView({ /> )} {inviteModalState.isOpen && ( - + )}
); diff --git a/src/room/InviteModal.tsx b/src/room/InviteModal.tsx index 781f2ed6..98c62298 100644 --- a/src/room/InviteModal.tsx +++ b/src/room/InviteModal.tsx @@ -1,5 +1,5 @@ /* -Copyright 2022 New Vector Ltd +Copyright 2022 - 2023 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,13 +21,15 @@ import { Modal, ModalContent, ModalProps } from "../Modal"; import { CopyButton } from "../button"; import { getRoomUrl } from "../matrix-utils"; import styles from "./InviteModal.module.css"; +import { useRoomSharedKey } from "../e2ee/sharedKeyManagement"; interface Props extends Omit { - roomIdOrAlias: string; + roomId: string; } -export const InviteModal: FC = ({ roomIdOrAlias, ...rest }) => { +export const InviteModal: FC = ({ roomId, ...rest }) => { const { t } = useTranslation(); + const roomSharedKey = useRoomSharedKey(roomId); return ( = ({ roomIdOrAlias, ...rest }) => {

{t("Copy and share this call link")}

diff --git a/src/room/LobbyView.tsx b/src/room/LobbyView.tsx index e1edadd5..a34595c9 100644 --- a/src/room/LobbyView.tsx +++ b/src/room/LobbyView.tsx @@ -14,14 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { - useRef, - useEffect, - useState, - useCallback, - ChangeEvent, - FC, -} from "react"; +import { useRef, useEffect, FC } from "react"; import { Trans, useTranslation } from "react-i18next"; import styles from "./LobbyView.module.css"; @@ -32,15 +25,13 @@ import { UserMenuContainer } from "../UserMenuContainer"; import { Body, Link } from "../typography/Typography"; import { useLocationNavigation } from "../useLocationNavigation"; import { MatrixInfo, VideoPreview } from "./VideoPreview"; -import { E2EEConfig } from "../livekit/useLiveKit"; -import { InputField } from "../input/Input"; -import { useEnableE2EE } from "../settings/useSetting"; import { MuteStates } from "./MuteStates"; +import { useRoomSharedKey } from "../e2ee/sharedKeyManagement"; interface Props { matrixInfo: MatrixInfo; muteStates: MuteStates; - onEnter: (e2eeConfig?: E2EEConfig) => void; + onEnter: () => void; isEmbedded: boolean; hideHeader: boolean; } @@ -53,10 +44,9 @@ export const LobbyView: FC = ({ hideHeader, }) => { const { t } = useTranslation(); + const roomSharedKey = useRoomSharedKey(matrixInfo.roomId); useLocationNavigation(); - const [enableE2EE] = useEnableE2EE(); - const joinCallButtonRef = useRef(null); useEffect(() => { if (joinCallButtonRef.current) { @@ -64,18 +54,6 @@ export const LobbyView: FC = ({ } }, [joinCallButtonRef]); - const [e2eeSharedKey, setE2EESharedKey] = useState( - undefined - ); - - const onE2EESharedKeyChanged = useCallback( - (event: ChangeEvent) => { - const value = event.target.value; - setE2EESharedKey(value === "" ? undefined : value); - }, - [setE2EESharedKey] - ); - return (
{!hideHeader && ( @@ -91,25 +69,12 @@ export const LobbyView: FC = ({
- {enableE2EE && ( - - )}