Merge pull request #1720 from vector-im/dbkr/write_key_with_right_roomid

Always store room passwords with the right room ID
This commit is contained in:
David Baker 2023-10-13 11:35:38 +01:00 committed by GitHub
commit 42d9fe1962
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -17,7 +17,7 @@ limitations under the License.
import { useEffect, useMemo } from "react"; import { useEffect, useMemo } from "react";
import { useEnableE2EE } from "../settings/useSetting"; import { useEnableE2EE } from "../settings/useSetting";
import { useLocalStorage } from "../useLocalStorage"; import { setLocalStorageItem, useLocalStorage } from "../useLocalStorage";
import { useClient } from "../ClientContext"; import { useClient } from "../ClientContext";
import { useUrlParams } from "../UrlParams"; import { useUrlParams } from "../UrlParams";
import { widget } from "../widget"; import { widget } from "../widget";
@ -25,39 +25,53 @@ import { widget } from "../widget";
export const getRoomSharedKeyLocalStorageKey = (roomId: string): string => export const getRoomSharedKeyLocalStorageKey = (roomId: string): string =>
`room-shared-key-${roomId}`; `room-shared-key-${roomId}`;
const useInternalRoomSharedKey = ( const useInternalRoomSharedKey = (roomId: string): string | null => {
roomId: string, const key = getRoomSharedKeyLocalStorageKey(roomId);
): [string | null, (value: string) => void] => {
const key = useMemo(() => getRoomSharedKeyLocalStorageKey(roomId), [roomId]);
const [e2eeEnabled] = useEnableE2EE(); const [e2eeEnabled] = useEnableE2EE();
const [roomSharedKey, setRoomSharedKey] = useLocalStorage(key); const roomSharedKey = useLocalStorage(key)[0];
return [e2eeEnabled ? roomSharedKey : null, setRoomSharedKey]; return e2eeEnabled ? roomSharedKey : null;
}; };
const useKeyFromUrl = (roomId: string): string | null => { /**
* Extracts the room password from the URL if one is present, saving it in localstorage
* and returning it in a tuple with the corresponding room ID from the URL.
* @returns A tuple of the roomId and password from the URL if the URL has both,
* otherwise [undefined, undefined]
*/
const useKeyFromUrl = (): [string, string] | [undefined, undefined] => {
const urlParams = useUrlParams(); const urlParams = useUrlParams();
const [e2eeSharedKey, setE2EESharedKey] = useInternalRoomSharedKey(roomId);
useEffect(() => { useEffect(() => {
if (!urlParams.password) return; if (!urlParams.password || !urlParams.roomId) return;
if (urlParams.password === "") return; if (!urlParams.roomId) return;
if (urlParams.password === e2eeSharedKey) return;
setE2EESharedKey(urlParams.password); setLocalStorageItem(
}, [urlParams, e2eeSharedKey, setE2EESharedKey]); // We set the Item by only using data from the url. This way we
// make sure, we always have matching pairs in the LocalStorage,
// as they occur in the call links.
getRoomSharedKeyLocalStorageKey(urlParams.roomId),
urlParams.password,
);
}, [urlParams]);
return urlParams.password ?? null; return urlParams.roomId && urlParams.password
? [urlParams.roomId, urlParams.password]
: [undefined, undefined];
}; };
export const useRoomSharedKey = (roomId: string): string | null => { export const useRoomSharedKey = (roomId: string): string | undefined => {
// make sure we've extracted the key from the URL first // make sure we've extracted the key from the URL first
// (and we still need to take the value it returns because // (and we still need to take the value it returns because
// the effect won't run in time for it to save to localstorage in // the effect won't run in time for it to save to localstorage in
// time for us to read it out again). // time for us to read it out again).
const passwordFormUrl = useKeyFromUrl(roomId); const [urlRoomId, passwordFormUrl] = useKeyFromUrl();
return useInternalRoomSharedKey(roomId)[0] ?? passwordFormUrl; const storedPassword = useInternalRoomSharedKey(roomId);
if (storedPassword) return storedPassword;
if (urlRoomId === roomId) return passwordFormUrl;
return undefined;
}; };
export const useIsRoomE2EE = (roomId: string): boolean | null => { export const useIsRoomE2EE = (roomId: string): boolean | null => {