From 34f8023a4eac0f8df0380ba618fe3a04d5614d83 Mon Sep 17 00:00:00 2001 From: Robert Long Date: Tue, 14 Dec 2021 18:25:52 -0800 Subject: [PATCH] Always authenticate user by registering temp guest accounts --- src/ConferenceCallManagerHooks.jsx | 265 +++++++++++------------------ src/Home.jsx | 11 +- src/Room.jsx | 26 +-- src/UserMenu.jsx | 41 ++--- 4 files changed, 130 insertions(+), 213 deletions(-) diff --git a/src/ConferenceCallManagerHooks.jsx b/src/ConferenceCallManagerHooks.jsx index d506780f..9dd4f8c6 100644 --- a/src/ConferenceCallManagerHooks.jsx +++ b/src/ConferenceCallManagerHooks.jsx @@ -65,6 +65,32 @@ async function initClient(clientOptions, guest) { return client; } +async function registerGuest(homeserverUrl) { + const registrationClient = matrix.createClient(homeserverUrl); + + const { user_id, device_id, access_token } = + await registrationClient.registerGuest({}); + + const client = await initClient( + { + baseUrl: homeserverUrl, + accessToken: access_token, + userId: user_id, + deviceId: device_id, + }, + true + ); + + await client.setDisplayName(`Guest ${client.getUserIdLocalpart()}`); + + localStorage.setItem( + "matrix-auth-store", + JSON.stringify({ user_id, device_id, access_token, guest: true }) + ); + + return client; +} + export async function fetchGroupCall( client, roomIdOrAlias, @@ -103,26 +129,15 @@ export async function fetchGroupCall( export function ClientProvider({ homeserverUrl, children }) { const history = useHistory(); - const [ - { - loading, - isAuthenticated, - isPasswordlessUser, - isGuest, - client, - userName, - displayName, - }, - setState, - ] = useState({ - loading: true, - isAuthenticated: false, - isPasswordlessUser: false, - isGuest: false, - client: undefined, - userName: null, - displayName: null, - }); + const [{ loading, isPasswordlessUser, isGuest, client, userName }, setState] = + useState({ + loading: true, + isPasswordlessUser: false, + isGuest: false, + client: undefined, + userName: null, + displayName: null, + }); useEffect(() => { async function restore() { @@ -156,8 +171,13 @@ export function ClientProvider({ homeserverUrl, children }) { return { client, guest, passwordlessUser }; } + } catch (err) { + localStorage.removeItem("matrix-auth-store"); + } - return { client: undefined, guest: false }; + try { + const client = await registerGuest(homeserverUrl); + return { client, guest: true, passwordlessUser: false }; } catch (err) { localStorage.removeItem("matrix-auth-store"); throw err; @@ -169,17 +189,16 @@ export function ClientProvider({ homeserverUrl, children }) { setState({ client, loading: false, - isAuthenticated: !!client, isPasswordlessUser: !!passwordlessUser, isGuest: guest, userName: client?.getUserIdLocalpart(), }); }) - .catch(() => { + .catch((error) => { setState({ + error, client: undefined, loading: false, - isAuthenticated: false, isPasswordlessUser: false, isGuest: false, userName: null, @@ -188,156 +207,82 @@ export function ClientProvider({ homeserverUrl, children }) { }, []); const login = useCallback(async (homeserver, username, password) => { - try { - let loginHomeserverUrl = homeserver.trim(); + let loginHomeserverUrl = homeserver.trim(); - if (!loginHomeserverUrl.includes("://")) { - loginHomeserverUrl = "https://" + loginHomeserverUrl; + if (!loginHomeserverUrl.includes("://")) { + loginHomeserverUrl = "https://" + loginHomeserverUrl; + } + + try { + const wellKnownUrl = new URL( + "/.well-known/matrix/client", + window.location + ); + const response = await fetch(wellKnownUrl); + const config = await response.json(); + + if (config["m.homeserver"]) { + loginHomeserverUrl = config["m.homeserver"]; } + } catch (error) {} - try { - const wellKnownUrl = new URL( - "/.well-known/matrix/client", - window.location - ); - const response = await fetch(wellKnownUrl); - const config = await response.json(); + const registrationClient = matrix.createClient(loginHomeserverUrl); - if (config["m.homeserver"]) { - loginHomeserverUrl = config["m.homeserver"]; - } - } catch (error) {} + const { user_id, device_id, access_token } = + await registrationClient.loginWithPassword(username, password); - const registrationClient = matrix.createClient(loginHomeserverUrl); + const client = await initClient({ + baseUrl: loginHomeserverUrl, + accessToken: access_token, + userId: user_id, + deviceId: device_id, + }); - const { user_id, device_id, access_token } = - await registrationClient.loginWithPassword(username, password); + localStorage.setItem( + "matrix-auth-store", + JSON.stringify({ user_id, device_id, access_token }) + ); - const client = await initClient({ - baseUrl: loginHomeserverUrl, - accessToken: access_token, - userId: user_id, - deviceId: device_id, - }); + setState({ + client, + loading: false, + isPasswordlessUser: false, + isGuest: false, + userName: client.getUserIdLocalpart(), + }); - localStorage.setItem( - "matrix-auth-store", - JSON.stringify({ user_id, device_id, access_token }) - ); - - setState({ - client, - loading: false, - isAuthenticated: true, - isPasswordlessUser: false, - isGuest: false, - userName: client.getUserIdLocalpart(), - }); - } catch (err) { - localStorage.removeItem("matrix-auth-store"); - setState({ - client: undefined, - loading: false, - isAuthenticated: false, - isPasswordlessUser: false, - isGuest: false, - userName: null, - }); - throw err; - } - }, []); - - const registerGuest = useCallback(async () => { - try { - const registrationClient = matrix.createClient(homeserverUrl); - - const { user_id, device_id, access_token } = - await registrationClient.registerGuest({}); - - const client = await initClient( - { - baseUrl: homeserverUrl, - accessToken: access_token, - userId: user_id, - deviceId: device_id, - }, - true - ); - - await client.setProfileInfo("displayname", { - displayname: `Guest ${client.getUserIdLocalpart()}`, - }); - - localStorage.setItem( - "matrix-auth-store", - JSON.stringify({ user_id, device_id, access_token, guest: true }) - ); - - setState({ - client, - loading: false, - isAuthenticated: true, - isGuest: true, - isPasswordlessUser: false, - userName: client.getUserIdLocalpart(), - }); - } catch (err) { - localStorage.removeItem("matrix-auth-store"); - setState({ - client: undefined, - loading: false, - isAuthenticated: false, - isPasswordlessUser: false, - isGuest: false, - userName: null, - }); - throw err; - } + return client; }, []); const register = useCallback(async (username, password, passwordlessUser) => { - try { - const registrationClient = matrix.createClient(homeserverUrl); + const registrationClient = matrix.createClient(homeserverUrl); - const { user_id, device_id, access_token } = - await registrationClient.register(username, password, null, { - type: "m.login.dummy", - }); - - const client = await initClient({ - baseUrl: homeserverUrl, - accessToken: access_token, - userId: user_id, - deviceId: device_id, + const { user_id, device_id, access_token } = + await registrationClient.register(username, password, null, { + type: "m.login.dummy", }); - localStorage.setItem( - "matrix-auth-store", - JSON.stringify({ user_id, device_id, access_token, passwordlessUser }) - ); + const client = await initClient({ + baseUrl: homeserverUrl, + accessToken: access_token, + userId: user_id, + deviceId: device_id, + }); - setState({ - client, - loading: false, - isGuest: false, - isAuthenticated: true, - isPasswordlessUser: passwordlessUser, - userName: client.getUserIdLocalpart(), - }); + localStorage.setItem( + "matrix-auth-store", + JSON.stringify({ user_id, device_id, access_token, passwordlessUser }) + ); - return client; - } catch (err) { - localStorage.removeItem("matrix-auth-store"); - setState({ - client: undefined, - loading: false, - isGuest: false, - isAuthenticated: false, - isPasswordlessUser: false, - userName: null, - }); - throw err; - } + setState({ + client, + loading: false, + isGuest: false, + isPasswordlessUser: passwordlessUser, + userName: client.getUserIdLocalpart(), + }); + + return client; }, []); const logout = useCallback(() => { @@ -348,24 +293,20 @@ export function ClientProvider({ homeserverUrl, children }) { const context = useMemo( () => ({ loading, - isAuthenticated, isPasswordlessUser, isGuest, client, login, - registerGuest, register, logout, userName, }), [ loading, - isAuthenticated, isPasswordlessUser, isGuest, client, login, - registerGuest, register, logout, userName, diff --git a/src/Home.jsx b/src/Home.jsx index 1ac5f2ea..e5c08799 100644 --- a/src/Home.jsx +++ b/src/Home.jsx @@ -32,14 +32,7 @@ import classNames from "classnames"; import { ErrorView, LoadingView } from "./FullScreenView"; export function Home() { - const { - isAuthenticated, - isGuest, - isPasswordlessUser, - loading, - error, - client, - } = useClient(); + const { isGuest, isPasswordlessUser, loading, error, client } = useClient(); const history = useHistory(); const { createRoomError, creatingRoom, createRoom } = useCreateRoom(); @@ -74,7 +67,7 @@ export function Home() { return ; } else if (error || createRoomError) { return ; - } else if (!isAuthenticated || isGuest) { + } else if (isGuest) { return ( { - if (!loading && !isAuthenticated) { - setRegisteringGuest(true); - - registerGuest() - .then(() => { - setRegisteringGuest(false); - }) - .catch((error) => { - setRegistrationError(error); - setRegisteringGuest(false); - }); - } - }, [loading, isAuthenticated]); - - if (loading || registeringGuest) { + if (loading) { return ; } - if (registrationError || error) { - return ; + if (error) { + return ; } return ; diff --git a/src/UserMenu.jsx b/src/UserMenu.jsx index b7d15883..49018c1c 100644 --- a/src/UserMenu.jsx +++ b/src/UserMenu.jsx @@ -15,7 +15,7 @@ import { ProfileModal } from "./ProfileModal"; export function UserMenu() { const location = useLocation(); const history = useHistory(); - const { isAuthenticated, isGuest, logout, userName, client } = useClient(); + const { isGuest, isPasswordlessUser, logout, userName, client } = useClient(); const { displayName } = useDisplayName(client); const { modalState, modalProps } = useModalTriggerState(); @@ -40,30 +40,31 @@ export function UserMenu() { ); const items = useMemo(() => { - const arr = []; - - if (isAuthenticated) { - arr.push({ + const arr = [ + { key: "user", icon: UserIcon, label: displayName || userName, + }, + ]; + + if (isGuest || isPasswordlessUser) { + arr.push({ + key: "login", + label: "Sign In", + icon: LoginIcon, }); } - if (!isAuthenticated || isGuest) { - arr.push( - { - key: "login", - label: "Sign In", - icon: LoginIcon, - }, - { - key: "register", - label: "Register", - icon: LoginIcon, - } - ); - } else { + if (isGuest) { + arr.push({ + key: "register", + label: "Register", + icon: LoginIcon, + }); + } + + if (!isGuest) { arr.push({ key: "logout", label: "Sign Out", @@ -72,7 +73,7 @@ export function UserMenu() { } return arr; - }, [isAuthenticated, isGuest, userName, displayName]); + }, [isGuest, isPasswordlessUser, userName, displayName]); return ( <>