From 5784a005dc9f3135c041c4fffa816d3609ff9bc2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 13 Jul 2022 14:34:15 +0100 Subject: [PATCH 1/3] Auto-register if displayName URL param is given Fixes https://github.com/vector-im/element-call/issues/442 --- src/auth/generateRandomName.ts | 4 +--- src/room/RoomAuthView.jsx | 35 +++++++--------------------------- src/room/RoomPage.jsx | 27 +++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/auth/generateRandomName.ts b/src/auth/generateRandomName.ts index b58c111..2232d35 100644 --- a/src/auth/generateRandomName.ts +++ b/src/auth/generateRandomName.ts @@ -19,7 +19,6 @@ import { adjectives, colors, animals, - Config, } from "unique-names-generator"; const elements = [ @@ -143,12 +142,11 @@ const elements = [ "oganesson", ]; -export function generateRandomName(config: Config): string { +export function generateRandomName(): string { return uniqueNamesGenerator({ dictionaries: [colors, adjectives, animals, elements], style: "lowerCase", length: 3, separator: "-", - ...config, }); } diff --git a/src/room/RoomAuthView.jsx b/src/room/RoomAuthView.jsx index 4bf2303..0561314 100644 --- a/src/room/RoomAuthView.jsx +++ b/src/room/RoomAuthView.jsx @@ -16,26 +16,21 @@ limitations under the License. import React, { useCallback, useState } from "react"; import styles from "./RoomAuthView.module.css"; -import { useClient } from "../ClientContext"; import { Button } from "../button"; import { Body, Caption, Link, Headline } from "../typography/Typography"; import { Header, HeaderLogo, LeftNav, RightNav } from "../Header"; import { useLocation } from "react-router-dom"; -import { useRecaptcha } from "../auth/useRecaptcha"; import { FieldRow, InputField, ErrorMessage } from "../input/Input"; -import { randomString } from "matrix-js-sdk/src/randomstring"; -import { useInteractiveRegistration } from "../auth/useInteractiveRegistration"; import { Form } from "../form/Form"; import { UserMenuContainer } from "../UserMenuContainer"; -import { generateRandomName } from "../auth/generateRandomName"; +import { useRegisterPasswordlessUser } from "../auth/useRegisterPasswordlessUser"; export function RoomAuthView() { - const { setClient } = useClient(); const [loading, setLoading] = useState(false); const [error, setError] = useState(); - const [privacyPolicyUrl, recaptchaKey, register] = - useInteractiveRegistration(); - const { execute, reset, recaptchaId } = useRecaptcha(recaptchaKey); + + const { registerPasswordlessUser, recaptchaId, privacyPolicyUrl } = + useRegisterPasswordlessUser(); const onSubmit = useCallback( (e) => { @@ -43,29 +38,13 @@ export function RoomAuthView() { const data = new FormData(e.target); const displayName = data.get("displayName"); - async function submit() { - setError(undefined); - setLoading(true); - const recaptchaResponse = await execute(); - const userName = generateRandomName(); - const [client, session] = await register( - userName, - randomString(16), - displayName, - recaptchaResponse, - true - ); - setClient(client, session); - } - - submit().catch((error) => { - console.error(error); + registerPasswordlessUser(displayName).catch((error) => { + console.error("Failed to register passwordless user", e); setLoading(false); setError(error); - reset(); }); }, - [register, reset, execute] + [registerPasswordlessUser] ); const location = useLocation(); diff --git a/src/room/RoomPage.jsx b/src/room/RoomPage.jsx index 1fe7eea..72f6bf4 100644 --- a/src/room/RoomPage.jsx +++ b/src/room/RoomPage.jsx @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { useMemo } from "react"; +import React, { useEffect, useMemo, useState } from "react"; import { useLocation, useParams } from "react-router-dom"; import { useClient } from "../ClientContext"; import { ErrorView, LoadingView } from "../FullScreenView"; @@ -22,6 +22,7 @@ import { RoomAuthView } from "./RoomAuthView"; import { GroupCallLoader } from "./GroupCallLoader"; import { GroupCallView } from "./GroupCallView"; import { MediaHandlerProvider } from "../settings/useMediaHandler"; +import { useRegisterPasswordlessUser } from "../auth/useRegisterPasswordlessUser"; export function RoomPage() { const { loading, isAuthenticated, error, client, isPasswordlessUser } = @@ -29,17 +30,37 @@ export function RoomPage() { const { roomId: maybeRoomId } = useParams(); const { hash, search } = useLocation(); - const [viaServers, isEmbedded, isPtt] = useMemo(() => { + const [viaServers, isEmbedded, isPtt, displayName] = useMemo(() => { const params = new URLSearchParams(search); return [ params.getAll("via"), params.has("embed"), params.get("ptt") === "true", + params.get("displayName"), ]; }, [search]); const roomId = (maybeRoomId || hash || "").toLowerCase(); + const { registerPasswordlessUser, recaptchaId } = + useRegisterPasswordlessUser(); + const [isRegistering, setIsRegistering] = useState(false); - if (loading) { + useEffect(() => { + // If we're not already authed and we've been given a display name as + // a URL param, automatically register a passwordless user + if (!isAuthenticated && displayName) { + setIsRegistering(true); + registerPasswordlessUser(displayName).finally(() => { + setIsRegistering(false); + }); + } + }, [ + isAuthenticated, + displayName, + setIsRegistering, + registerPasswordlessUser, + ]); + + if (loading || isRegistering) { return ; } From c1e45c4a303db294470603add7e95ef7f7cb0d97 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 13 Jul 2022 16:02:17 +0100 Subject: [PATCH 2/3] Missed a file --- src/auth/useRegisterPasswordlessUser.ts | 59 +++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/auth/useRegisterPasswordlessUser.ts diff --git a/src/auth/useRegisterPasswordlessUser.ts b/src/auth/useRegisterPasswordlessUser.ts new file mode 100644 index 0000000..2fd7457 --- /dev/null +++ b/src/auth/useRegisterPasswordlessUser.ts @@ -0,0 +1,59 @@ +/* +Copyright 2022 Matrix.org Foundation C.I.C. + +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 { useCallback } from "react"; +import { randomString } from "matrix-js-sdk/src/randomstring"; + +import { useClient } from "../ClientContext"; +import { useInteractiveRegistration } from "../auth/useInteractiveRegistration"; +import { generateRandomName } from "../auth/generateRandomName"; +import { useRecaptcha } from "../auth/useRecaptcha"; + +export interface UseRegisterPasswordlessUserType { + privacyPolicyUrl: string; + registerPasswordlessUser: (string) => Promise; + recaptchaId: string; +} + +export function useRegisterPasswordlessUser(): UseRegisterPasswordlessUserType { + const { setClient } = useClient(); + const [privacyPolicyUrl, recaptchaKey, register] = + useInteractiveRegistration(); + const { execute, reset, recaptchaId } = useRecaptcha(recaptchaKey); + + const registerPasswordlessUser = useCallback( + async (displayName: string) => { + try { + const recaptchaResponse = await execute(); + const userName = generateRandomName(); + const [client, session] = await register( + userName, + randomString(16), + displayName, + recaptchaResponse, + true + ); + setClient(client, session); + } catch (e) { + reset(); + throw e; + } + }, + [execute, reset, register, setClient] + ); + + return { privacyPolicyUrl, registerPasswordlessUser, recaptchaId }; +} From 1eab957d85080332350da730aeceb3f526373c4b Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 14 Jul 2022 13:11:47 +0100 Subject: [PATCH 3/3] Fix typescript syntax --- src/auth/useRegisterPasswordlessUser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auth/useRegisterPasswordlessUser.ts b/src/auth/useRegisterPasswordlessUser.ts index 2fd7457..7318947 100644 --- a/src/auth/useRegisterPasswordlessUser.ts +++ b/src/auth/useRegisterPasswordlessUser.ts @@ -24,7 +24,7 @@ import { useRecaptcha } from "../auth/useRecaptcha"; export interface UseRegisterPasswordlessUserType { privacyPolicyUrl: string; - registerPasswordlessUser: (string) => Promise; + registerPasswordlessUser: (displayName: string) => Promise; recaptchaId: string; }