diff --git a/package.json b/package.json
index 97a9214..b101275 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,8 @@
"react-router": "6",
"react-router-dom": "^5.2.0",
"react-use-clipboard": "^1.0.7",
- "react-use-measure": "^2.1.1"
+ "react-use-measure": "^2.1.1",
+ "unique-names-generator": "^4.6.0"
},
"devDependencies": {
"@babel/core": "^7.16.5",
diff --git a/src/ClientContext.jsx b/src/ClientContext.jsx
index 20ccd89..91d756a 100644
--- a/src/ClientContext.jsx
+++ b/src/ClientContext.jsx
@@ -145,29 +145,36 @@ export function ClientProvider({ children }) {
[client]
);
- const setClient = useCallback((client, session) => {
- if (client) {
- localStorage.setItem("matrix-auth-store", JSON.stringify(session));
+ const setClient = useCallback(
+ (newClient, session) => {
+ if (client && client !== newClient) {
+ client.stopClient();
+ }
- setState({
- client,
- loading: false,
- isAuthenticated: true,
- isPasswordlessUser: !!session.passwordlessUser,
- userName: client.getUserIdLocalpart(),
- });
- } else {
- localStorage.removeItem("matrix-auth-store");
+ if (newClient) {
+ localStorage.setItem("matrix-auth-store", JSON.stringify(session));
- setState({
- client: undefined,
- loading: false,
- isAuthenticated: false,
- isPasswordlessUser: false,
- userName: null,
- });
- }
- }, []);
+ setState({
+ client: newClient,
+ loading: false,
+ isAuthenticated: true,
+ isPasswordlessUser: !!session.passwordlessUser,
+ userName: newClient.getUserIdLocalpart(),
+ });
+ } else {
+ localStorage.removeItem("matrix-auth-store");
+
+ setState({
+ client: undefined,
+ loading: false,
+ isAuthenticated: false,
+ isPasswordlessUser: false,
+ userName: null,
+ });
+ }
+ },
+ [client]
+ );
const logout = useCallback(() => {
localStorage.removeItem("matrix-auth-store");
@@ -226,6 +233,10 @@ export function ClientProvider({ children }) {
]
);
+ useEffect(() => {
+ window.matrixclient = client;
+ }, [client]);
+
if (error) {
return ;
}
diff --git a/src/auth/RegisterPage.jsx b/src/auth/RegisterPage.jsx
index 70eeaaf..6f08acb 100644
--- a/src/auth/RegisterPage.jsx
+++ b/src/auth/RegisterPage.jsx
@@ -31,13 +31,7 @@ import { usePageTitle } from "../usePageTitle";
export function RegisterPage() {
usePageTitle("Register");
- const {
- loading,
- client,
- changePassword,
- isAuthenticated,
- isPasswordlessUser,
- } = useClient();
+ const { loading, isAuthenticated, isPasswordlessUser, client } = useClient();
const confirmPasswordRef = useRef();
const history = useHistory();
const location = useLocation();
@@ -64,11 +58,31 @@ export function RegisterPage() {
async function submit() {
setRegistering(true);
- if (isPasswordlessUser) {
- await changePassword(password);
- } else {
- const recaptchaResponse = await execute();
- await register(userName, password, recaptchaResponse);
+ let roomIds;
+
+ if (client && isPasswordlessUser) {
+ const groupCalls = client.groupCallEventHandler.groupCalls.values();
+ roomIds = Array.from(groupCalls).map(
+ (groupCall) => groupCall.room.roomId
+ );
+ }
+
+ const recaptchaResponse = await execute();
+ const newClient = await register(
+ userName,
+ password,
+ userName,
+ recaptchaResponse
+ );
+
+ if (roomIds) {
+ for (const roomId of roomIds) {
+ try {
+ await newClient.joinRoom(roomId);
+ } catch (error) {
+ console.warn(`Couldn't join room ${roomId}`, error);
+ }
+ }
}
}
@@ -86,15 +100,7 @@ export function RegisterPage() {
reset();
});
},
- [
- register,
- changePassword,
- location,
- history,
- isPasswordlessUser,
- reset,
- execute,
- ]
+ [register, location, history, isPasswordlessUser, reset, execute, client]
);
useEffect(() => {
@@ -110,10 +116,10 @@ export function RegisterPage() {
}, [password, passwordConfirmation]);
useEffect(() => {
- if (!loading && isAuthenticated && !isPasswordlessUser) {
+ if (!loading && isAuthenticated && !isPasswordlessUser && !registering) {
history.push("/");
}
- }, [history, isAuthenticated, isPasswordlessUser]);
+ }, [history, isAuthenticated, isPasswordlessUser, registering]);
if (loading) {
return ;
@@ -137,12 +143,6 @@ export function RegisterPage() {
autoCapitalize="none"
prefix="@"
suffix={`:${defaultHomeserverHost}`}
- value={
- isAuthenticated && isPasswordlessUser
- ? client.getUserIdLocalpart()
- : undefined
- }
- disabled={isAuthenticated && isPasswordlessUser}
/>
@@ -168,22 +168,20 @@ export function RegisterPage() {
ref={confirmPasswordRef}
/>
- {!isPasswordlessUser && (
-
- This site is protected by ReCAPTCHA and the Google{" "}
-
- Privacy Policy
- {" "}
- and{" "}
-
- Terms of Service
- {" "}
- apply.
-
- By clicking "Log in", you agree to our{" "}
- Terms and conditions
-
- )}
+
+ This site is protected by ReCAPTCHA and the Google{" "}
+
+ Privacy Policy
+ {" "}
+ and{" "}
+
+ Terms of Service
+ {" "}
+ apply.
+
+ By clicking "Register", you agree to our{" "}
+ Terms and conditions
+
{error && (
{error.message}
diff --git a/src/auth/generateRandomName.js b/src/auth/generateRandomName.js
new file mode 100644
index 0000000..7e6ff93
--- /dev/null
+++ b/src/auth/generateRandomName.js
@@ -0,0 +1,137 @@
+import {
+ uniqueNamesGenerator,
+ adjectives,
+ colors,
+ animals,
+} from "unique-names-generator";
+
+const elements = [
+ "hydrogen",
+ "helium",
+ "lithium",
+ "beryllium",
+ "boron",
+ "carbon",
+ "nitrogen",
+ "oxygen",
+ "fluorine",
+ "neon",
+ "sodium",
+ "magnesium",
+ "aluminum",
+ "silicon",
+ "phosphorus",
+ "sulfur",
+ "chlorine",
+ "argon",
+ "potassium",
+ "calcium",
+ "scandium",
+ "titanium",
+ "vanadium",
+ "chromium",
+ "manganese",
+ "iron",
+ "cobalt",
+ "nickel",
+ "copper",
+ "zinc",
+ "gallium",
+ "germanium",
+ "arsenic",
+ "selenium",
+ "bromine",
+ "krypton",
+ "rubidium",
+ "strontium",
+ "yttrium",
+ "zirconium",
+ "niobium",
+ "molybdenum",
+ "technetium",
+ "ruthenium",
+ "rhodium",
+ "palladium",
+ "silver",
+ "cadmium",
+ "indium",
+ "tin",
+ "antimony",
+ "tellurium",
+ "iodine",
+ "xenon",
+ "cesium",
+ "barium",
+ "lanthanum",
+ "cerium",
+ "praseodymium",
+ "neodymium",
+ "promethium",
+ "samarium",
+ "europium",
+ "gadolinium",
+ "terbium",
+ "dysprosium",
+ "holmium",
+ "erbium",
+ "thulium",
+ "ytterbium",
+ "lutetium",
+ "hafnium",
+ "tantalum",
+ "wolfram",
+ "rhenium",
+ "osmium",
+ "iridium",
+ "platinum",
+ "gold",
+ "mercury",
+ "thallium",
+ "lead",
+ "bismuth",
+ "polonium",
+ "astatine",
+ "radon",
+ "francium",
+ "radium",
+ "actinium",
+ "thorium",
+ "protactinium",
+ "uranium",
+ "neptunium",
+ "plutonium",
+ "americium",
+ "curium",
+ "berkelium",
+ "californium",
+ "einsteinium",
+ "fermium",
+ "mendelevium",
+ "nobelium",
+ "lawrencium",
+ "rutherfordium",
+ "dubnium",
+ "seaborgium",
+ "bohrium",
+ "hassium",
+ "meitnerium",
+ "darmstadtium",
+ "roentgenium",
+ "copernicium",
+ "nihonium",
+ "flerovium",
+ "moscovium",
+ "livermorium",
+ "tennessine",
+ "oganesson",
+];
+
+export function generateRandomName(config) {
+ return uniqueNamesGenerator({
+ dictionaries: [colors, adjectives, animals, elements],
+ style: "lowerCase",
+ length: 3,
+ separator: "-",
+ ...config,
+ });
+}
diff --git a/src/auth/useInteractiveRegistration.js b/src/auth/useInteractiveRegistration.js
index fc398a1..dbddbb0 100644
--- a/src/auth/useInteractiveRegistration.js
+++ b/src/auth/useInteractiveRegistration.js
@@ -25,7 +25,13 @@ export function useInteractiveRegistration() {
}, []);
const register = useCallback(
- async (username, password, recaptchaResponse, passwordlessUser) => {
+ async (
+ username,
+ password,
+ displayName,
+ recaptchaResponse,
+ passwordlessUser
+ ) => {
const interactiveAuth = new InteractiveAuth({
matrixClient: authClientRef.current,
busyChanged(loading) {
@@ -66,7 +72,7 @@ export function useInteractiveRegistration() {
deviceId: device_id,
});
- await client.setDisplayName(username);
+ await client.setDisplayName(displayName);
const session = { user_id, device_id, access_token, passwordlessUser };
diff --git a/src/home/UnauthenticatedView.jsx b/src/home/UnauthenticatedView.jsx
index fb6fe42..21db6ac 100644
--- a/src/home/UnauthenticatedView.jsx
+++ b/src/home/UnauthenticatedView.jsx
@@ -14,6 +14,7 @@ import { Body, Caption, Link, Headline } from "../typography/Typography";
import { Form } from "../form/Form";
import styles from "./UnauthenticatedView.module.css";
import commonStyles from "./common.module.css";
+import { generateRandomName } from "../auth/generateRandomName";
export function UnauthenticatedView() {
const [loading, setLoading] = useState(false);
@@ -26,19 +27,20 @@ export function UnauthenticatedView() {
e.preventDefault();
const data = new FormData(e.target);
const roomName = data.get("callName");
- const userName = data.get("userName");
+ const displayName = data.get("displayName");
async function submit() {
setError(undefined);
setLoading(true);
const recaptchaResponse = await execute();
+ const userName = generateRandomName();
const client = await register(
userName,
randomString(16),
+ displayName,
recaptchaResponse,
true
);
-
const roomIdOrAlias = await createRoom(client, roomName);
if (roomIdOrAlias) {
@@ -100,10 +102,10 @@ export function UnauthenticatedView() {
{
e.preventDefault();
const data = new FormData(e.target);
- const userName = data.get("userName");
+ const displayName = data.get("displayName");
async function submit() {
setError(undefined);
setLoading(true);
const recaptchaResponse = await execute();
- await register(userName, randomString(16), recaptchaResponse, true);
+ const userName = generateRandomName();
+ await register(
+ userName,
+ randomString(16),
+ displayName,
+ recaptchaResponse,
+ true
+ );
}
submit().catch((error) => {
@@ -58,10 +66,10 @@ export function RoomAuthView() {