Move e2ee options to index page (#155)

* Move e2ee options to index page

* update readme

* use localuserchoices
This commit is contained in:
lukasIO 2023-11-10 11:30:32 +02:00 committed by GitHub
parent 8fa50fd7d7
commit 789e994c3a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 25 deletions

View file

@ -39,8 +39,14 @@ function Tabs(props: TabsProps) {
function DemoMeetingTab({ label }: { label: string }) { function DemoMeetingTab({ label }: { label: string }) {
const router = useRouter(); const router = useRouter();
const [e2ee, setE2ee] = useState(false);
const [sharedPassphrase, setSharedPassphrase] = useState(randomString(64));
const startMeeting = () => { const startMeeting = () => {
router.push(`/rooms/${generateRoomId()}`); if (e2ee) {
router.push(`/rooms/${generateRoomId()}#${encodePassphrase(sharedPassphrase)}`);
} else {
router.push(`/rooms/${generateRoomId()}`);
}
}; };
return ( return (
<div className={styles.tabContent}> <div className={styles.tabContent}>
@ -48,6 +54,28 @@ function DemoMeetingTab({ label }: { label: string }) {
<button style={{ marginTop: '1rem' }} className="lk-button" onClick={startMeeting}> <button style={{ marginTop: '1rem' }} className="lk-button" onClick={startMeeting}>
Start Meeting Start Meeting
</button> </button>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<div style={{ display: 'flex', flexDirection: 'row', gap: '1rem' }}>
<input
id="use-e2ee"
type="checkbox"
checked={e2ee}
onChange={(ev) => setE2ee(ev.target.checked)}
></input>
<label htmlFor="use-e2ee">Enable end-to-end encryption</label>
</div>
{e2ee && (
<div style={{ display: 'flex', flexDirection: 'row', gap: '1rem' }}>
<label htmlFor="passphrase">Passphrase</label>
<input
id="passphrase"
type="password"
value={sharedPassphrase}
onChange={(ev) => setSharedPassphrase(ev.target.value)}
/>
</div>
)}
</div>
</div> </div>
); );
} }

View file

@ -1,12 +1,13 @@
'use client'; 'use client';
import { import {
LiveKitRoom, LiveKitRoom,
LocalUserChoices,
VideoConference, VideoConference,
formatChatMessageLinks, formatChatMessageLinks,
useToken, useToken,
LocalUserChoices,
} from '@livekit/components-react'; } from '@livekit/components-react';
import { import {
DeviceUnsupportedError,
ExternalE2EEKeyProvider, ExternalE2EEKeyProvider,
LogLevel, LogLevel,
Room, Room,
@ -20,14 +21,9 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import Head from 'next/head'; import Head from 'next/head';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useMemo, useState } from 'react'; import * as React from 'react';
import { DebugMode } from '../../lib/Debug'; import { DebugMode } from '../../lib/Debug';
import { import { decodePassphrase, useServerUrl } from '../../lib/client-utils';
decodePassphrase,
encodePassphrase,
randomString,
useServerUrl,
} from '../../lib/client-utils';
const PreJoinNoSSR = dynamic( const PreJoinNoSSR = dynamic(
async () => { async () => {
@ -39,15 +35,12 @@ const PreJoinNoSSR = dynamic(
const Home: NextPage = () => { const Home: NextPage = () => {
const router = useRouter(); const router = useRouter();
const { name: roomName } = router.query; const { name: roomName } = router.query;
const e2eePassphrase =
typeof window !== 'undefined' && decodePassphrase(location.hash.substring(1));
const [preJoinChoices, setPreJoinChoices] = useState<LocalUserChoices | undefined>(undefined); const [preJoinChoices, setPreJoinChoices] = React.useState<LocalUserChoices | undefined>(
undefined,
);
function handlePreJoinSubmit(values: LocalUserChoices) { function handlePreJoinSubmit(values: LocalUserChoices) {
if (values.e2ee) {
location.hash = encodePassphrase(values.sharedPassphrase);
}
setPreJoinChoices(values); setPreJoinChoices(values);
} }
return ( return (
@ -74,11 +67,8 @@ const Home: NextPage = () => {
username: '', username: '',
videoEnabled: true, videoEnabled: true,
audioEnabled: true, audioEnabled: true,
e2ee: !!e2eePassphrase,
sharedPassphrase: e2eePassphrase || randomString(64),
}} }}
onSubmit={handlePreJoinSubmit} onSubmit={handlePreJoinSubmit}
showE2EEOptions={true}
></PreJoinNoSSR> ></PreJoinNoSSR>
</div> </div>
)} )}
@ -106,17 +96,20 @@ const ActiveRoom = ({ roomName, userChoices, onLeave }: ActiveRoomProps) => {
const router = useRouter(); const router = useRouter();
const { region, hq, codec } = router.query; const { region, hq, codec } = router.query;
const e2eePassphrase =
typeof window !== 'undefined' && decodePassphrase(location.hash.substring(1));
const liveKitUrl = useServerUrl(region as string | undefined); const liveKitUrl = useServerUrl(region as string | undefined);
const worker = const worker =
typeof window !== 'undefined' && typeof window !== 'undefined' &&
userChoices.e2ee && e2eePassphrase &&
new Worker(new URL('livekit-client/e2ee-worker', import.meta.url)); new Worker(new URL('livekit-client/e2ee-worker', import.meta.url));
const e2eeEnabled = !!(userChoices.e2ee && worker); const e2eeEnabled = !!(e2eePassphrase && worker);
const keyProvider = new ExternalE2EEKeyProvider(); const keyProvider = new ExternalE2EEKeyProvider();
const roomOptions = useMemo((): RoomOptions => { const roomOptions = React.useMemo((): RoomOptions => {
return { return {
videoCaptureDefaults: { videoCaptureDefaults: {
deviceId: userChoices.videoDeviceId ?? undefined, deviceId: userChoices.videoDeviceId ?? undefined,
@ -145,13 +138,20 @@ const ActiveRoom = ({ roomName, userChoices, onLeave }: ActiveRoomProps) => {
}; };
}, [userChoices, hq, codec]); }, [userChoices, hq, codec]);
const room = useMemo(() => new Room(roomOptions), []); const room = React.useMemo(() => new Room(roomOptions), []);
if (e2eeEnabled) { if (e2eeEnabled) {
keyProvider.setKey(decodePassphrase(userChoices.sharedPassphrase)); keyProvider.setKey(decodePassphrase(e2eePassphrase));
room.setE2EEEnabled(true); room.setE2EEEnabled(true).catch((e) => {
if (e instanceof DeviceUnsupportedError) {
alert(
`You're trying to join an encrypted meeting, but your browser does not support it. Please update it to the latest version and try again.`,
);
console.error(e);
}
});
} }
const connectOptions = useMemo((): RoomConnectOptions => { const connectOptions = React.useMemo((): RoomConnectOptions => {
return { return {
autoSubscribe: true, autoSubscribe: true,
}; };