Auto-register if displayName URL param is given

Fixes https://github.com/vector-im/element-call/issues/442
This commit is contained in:
David Baker 2022-07-13 14:34:15 +01:00
parent a3e4d6998f
commit 5784a005dc
3 changed files with 32 additions and 34 deletions

View File

@ -19,7 +19,6 @@ import {
adjectives, adjectives,
colors, colors,
animals, animals,
Config,
} from "unique-names-generator"; } from "unique-names-generator";
const elements = [ const elements = [
@ -143,12 +142,11 @@ const elements = [
"oganesson", "oganesson",
]; ];
export function generateRandomName(config: Config): string { export function generateRandomName(): string {
return uniqueNamesGenerator({ return uniqueNamesGenerator({
dictionaries: [colors, adjectives, animals, elements], dictionaries: [colors, adjectives, animals, elements],
style: "lowerCase", style: "lowerCase",
length: 3, length: 3,
separator: "-", separator: "-",
...config,
}); });
} }

View File

@ -16,26 +16,21 @@ limitations under the License.
import React, { useCallback, useState } from "react"; import React, { useCallback, useState } from "react";
import styles from "./RoomAuthView.module.css"; import styles from "./RoomAuthView.module.css";
import { useClient } from "../ClientContext";
import { Button } from "../button"; import { Button } from "../button";
import { Body, Caption, Link, Headline } from "../typography/Typography"; import { Body, Caption, Link, Headline } from "../typography/Typography";
import { Header, HeaderLogo, LeftNav, RightNav } from "../Header"; import { Header, HeaderLogo, LeftNav, RightNav } from "../Header";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { useRecaptcha } from "../auth/useRecaptcha";
import { FieldRow, InputField, ErrorMessage } from "../input/Input"; 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 { Form } from "../form/Form";
import { UserMenuContainer } from "../UserMenuContainer"; import { UserMenuContainer } from "../UserMenuContainer";
import { generateRandomName } from "../auth/generateRandomName"; import { useRegisterPasswordlessUser } from "../auth/useRegisterPasswordlessUser";
export function RoomAuthView() { export function RoomAuthView() {
const { setClient } = useClient();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState(); const [error, setError] = useState();
const [privacyPolicyUrl, recaptchaKey, register] =
useInteractiveRegistration(); const { registerPasswordlessUser, recaptchaId, privacyPolicyUrl } =
const { execute, reset, recaptchaId } = useRecaptcha(recaptchaKey); useRegisterPasswordlessUser();
const onSubmit = useCallback( const onSubmit = useCallback(
(e) => { (e) => {
@ -43,29 +38,13 @@ export function RoomAuthView() {
const data = new FormData(e.target); const data = new FormData(e.target);
const displayName = data.get("displayName"); const displayName = data.get("displayName");
async function submit() { registerPasswordlessUser(displayName).catch((error) => {
setError(undefined); console.error("Failed to register passwordless user", e);
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);
setLoading(false); setLoading(false);
setError(error); setError(error);
reset();
}); });
}, },
[register, reset, execute] [registerPasswordlessUser]
); );
const location = useLocation(); const location = useLocation();

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React, { useMemo } from "react"; import React, { useEffect, useMemo, useState } from "react";
import { useLocation, useParams } from "react-router-dom"; import { useLocation, useParams } from "react-router-dom";
import { useClient } from "../ClientContext"; import { useClient } from "../ClientContext";
import { ErrorView, LoadingView } from "../FullScreenView"; import { ErrorView, LoadingView } from "../FullScreenView";
@ -22,6 +22,7 @@ import { RoomAuthView } from "./RoomAuthView";
import { GroupCallLoader } from "./GroupCallLoader"; import { GroupCallLoader } from "./GroupCallLoader";
import { GroupCallView } from "./GroupCallView"; import { GroupCallView } from "./GroupCallView";
import { MediaHandlerProvider } from "../settings/useMediaHandler"; import { MediaHandlerProvider } from "../settings/useMediaHandler";
import { useRegisterPasswordlessUser } from "../auth/useRegisterPasswordlessUser";
export function RoomPage() { export function RoomPage() {
const { loading, isAuthenticated, error, client, isPasswordlessUser } = const { loading, isAuthenticated, error, client, isPasswordlessUser } =
@ -29,17 +30,37 @@ export function RoomPage() {
const { roomId: maybeRoomId } = useParams(); const { roomId: maybeRoomId } = useParams();
const { hash, search } = useLocation(); const { hash, search } = useLocation();
const [viaServers, isEmbedded, isPtt] = useMemo(() => { const [viaServers, isEmbedded, isPtt, displayName] = useMemo(() => {
const params = new URLSearchParams(search); const params = new URLSearchParams(search);
return [ return [
params.getAll("via"), params.getAll("via"),
params.has("embed"), params.has("embed"),
params.get("ptt") === "true", params.get("ptt") === "true",
params.get("displayName"),
]; ];
}, [search]); }, [search]);
const roomId = (maybeRoomId || hash || "").toLowerCase(); 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 <LoadingView />; return <LoadingView />;
} }