Clean up old auth logic
This commit is contained in:
@@ -21,9 +21,8 @@ import React, {
|
|||||||
createContext,
|
createContext,
|
||||||
useMemo,
|
useMemo,
|
||||||
useContext,
|
useContext,
|
||||||
useRef,
|
|
||||||
} from "react";
|
} from "react";
|
||||||
import matrix, { InteractiveAuth } from "matrix-js-sdk/src/browser-index";
|
import matrix from "matrix-js-sdk/src/browser-index";
|
||||||
import {
|
import {
|
||||||
GroupCallIntent,
|
GroupCallIntent,
|
||||||
GroupCallType,
|
GroupCallType,
|
||||||
@@ -53,13 +52,9 @@ function waitForSync(client) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initClient(clientOptions, guest) {
|
export async function initClient(clientOptions) {
|
||||||
const client = matrix.createClient(clientOptions);
|
const client = matrix.createClient(clientOptions);
|
||||||
|
|
||||||
if (guest) {
|
|
||||||
client.setGuest(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
await client.startClient({
|
await client.startClient({
|
||||||
// dirty hack to reduce chance of gappy syncs
|
// dirty hack to reduce chance of gappy syncs
|
||||||
// should be fixed by spotting gaps and backpaginating
|
// should be fixed by spotting gaps and backpaginating
|
||||||
@@ -110,13 +105,12 @@ export async function fetchGroupCall(
|
|||||||
export function ClientProvider({ children }) {
|
export function ClientProvider({ children }) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [
|
const [
|
||||||
{ loading, isAuthenticated, isPasswordlessUser, isGuest, client, userName },
|
{ loading, isAuthenticated, isPasswordlessUser, client, userName },
|
||||||
setState,
|
setState,
|
||||||
] = useState({
|
] = useState({
|
||||||
loading: true,
|
loading: true,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
isPasswordlessUser: false,
|
isPasswordlessUser: false,
|
||||||
isGuest: false,
|
|
||||||
client: undefined,
|
client: undefined,
|
||||||
userName: null,
|
userName: null,
|
||||||
});
|
});
|
||||||
@@ -131,20 +125,16 @@ export function ClientProvider({ children }) {
|
|||||||
user_id,
|
user_id,
|
||||||
device_id,
|
device_id,
|
||||||
access_token,
|
access_token,
|
||||||
guest,
|
|
||||||
passwordlessUser,
|
passwordlessUser,
|
||||||
tempPassword,
|
tempPassword,
|
||||||
} = JSON.parse(authStore);
|
} = JSON.parse(authStore);
|
||||||
|
|
||||||
const client = await initClient(
|
const client = await initClient({
|
||||||
{
|
baseUrl: defaultHomeserver,
|
||||||
baseUrl: defaultHomeserver,
|
accessToken: access_token,
|
||||||
accessToken: access_token,
|
userId: user_id,
|
||||||
userId: user_id,
|
deviceId: device_id,
|
||||||
deviceId: device_id,
|
});
|
||||||
},
|
|
||||||
guest
|
|
||||||
);
|
|
||||||
|
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
"matrix-auth-store",
|
"matrix-auth-store",
|
||||||
@@ -152,16 +142,16 @@ export function ClientProvider({ children }) {
|
|||||||
user_id,
|
user_id,
|
||||||
device_id,
|
device_id,
|
||||||
access_token,
|
access_token,
|
||||||
guest,
|
|
||||||
passwordlessUser,
|
passwordlessUser,
|
||||||
tempPassword,
|
tempPassword,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
return { client, guest, passwordlessUser };
|
return { client, passwordlessUser };
|
||||||
}
|
}
|
||||||
|
|
||||||
return { client: undefined, guest: false };
|
return { client: undefined };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
localStorage.removeItem("matrix-auth-store");
|
localStorage.removeItem("matrix-auth-store");
|
||||||
throw err;
|
throw err;
|
||||||
@@ -169,13 +159,12 @@ export function ClientProvider({ children }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
restore()
|
restore()
|
||||||
.then(({ client, guest, passwordlessUser }) => {
|
.then(({ client, passwordlessUser }) => {
|
||||||
setState({
|
setState({
|
||||||
client,
|
client,
|
||||||
loading: false,
|
loading: false,
|
||||||
isAuthenticated: !!client,
|
isAuthenticated: !!client,
|
||||||
isPasswordlessUser: !!passwordlessUser,
|
isPasswordlessUser: !!passwordlessUser,
|
||||||
isGuest: guest,
|
|
||||||
userName: client?.getUserIdLocalpart(),
|
userName: client?.getUserIdLocalpart(),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@@ -185,168 +174,11 @@ export function ClientProvider({ children }) {
|
|||||||
loading: false,
|
loading: false,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
isPasswordlessUser: false,
|
isPasswordlessUser: false,
|
||||||
isGuest: false,
|
|
||||||
userName: null,
|
userName: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const login = useCallback(async (homeserver, username, password) => {
|
|
||||||
try {
|
|
||||||
let loginHomeserverUrl = homeserver.trim();
|
|
||||||
|
|
||||||
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) {}
|
|
||||||
|
|
||||||
const registrationClient = matrix.createClient(loginHomeserverUrl);
|
|
||||||
|
|
||||||
const { user_id, device_id, access_token } =
|
|
||||||
await registrationClient.loginWithPassword(username, password);
|
|
||||||
|
|
||||||
const client = await initClient({
|
|
||||||
baseUrl: loginHomeserverUrl,
|
|
||||||
accessToken: access_token,
|
|
||||||
userId: user_id,
|
|
||||||
deviceId: device_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
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(defaultHomeserver);
|
|
||||||
|
|
||||||
const { user_id, device_id, access_token } =
|
|
||||||
await registrationClient.registerGuest({});
|
|
||||||
|
|
||||||
const client = await initClient(
|
|
||||||
{
|
|
||||||
baseUrl: defaultHomeserver,
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const register = useCallback(async (username, password, passwordlessUser) => {
|
|
||||||
try {
|
|
||||||
const registrationClient = matrix.createClient(defaultHomeserver);
|
|
||||||
|
|
||||||
const { user_id, device_id, access_token } =
|
|
||||||
await registrationClient.register(username, password, null, {
|
|
||||||
type: "m.login.dummy",
|
|
||||||
});
|
|
||||||
|
|
||||||
const client = await initClient({
|
|
||||||
baseUrl: defaultHomeserver,
|
|
||||||
accessToken: access_token,
|
|
||||||
userId: user_id,
|
|
||||||
deviceId: device_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
const session = { user_id, device_id, access_token, passwordlessUser };
|
|
||||||
|
|
||||||
if (passwordlessUser) {
|
|
||||||
session.tempPassword = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem("matrix-auth-store", JSON.stringify(session));
|
|
||||||
|
|
||||||
setState({
|
|
||||||
client,
|
|
||||||
loading: false,
|
|
||||||
isGuest: false,
|
|
||||||
isAuthenticated: true,
|
|
||||||
isPasswordlessUser: passwordlessUser,
|
|
||||||
userName: client.getUserIdLocalpart(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return client;
|
|
||||||
} catch (err) {
|
|
||||||
localStorage.removeItem("matrix-auth-store");
|
|
||||||
setState({
|
|
||||||
client: undefined,
|
|
||||||
loading: false,
|
|
||||||
isGuest: false,
|
|
||||||
isAuthenticated: false,
|
|
||||||
isPasswordlessUser: false,
|
|
||||||
userName: null,
|
|
||||||
});
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const changePassword = useCallback(
|
const changePassword = useCallback(
|
||||||
async (password) => {
|
async (password) => {
|
||||||
const { tempPassword, passwordlessUser, ...existingSession } = JSON.parse(
|
const { tempPassword, passwordlessUser, ...existingSession } = JSON.parse(
|
||||||
@@ -377,7 +209,6 @@ export function ClientProvider({ children }) {
|
|||||||
setState({
|
setState({
|
||||||
client,
|
client,
|
||||||
loading: false,
|
loading: false,
|
||||||
isGuest: false,
|
|
||||||
isAuthenticated: true,
|
isAuthenticated: true,
|
||||||
isPasswordlessUser: false,
|
isPasswordlessUser: false,
|
||||||
userName: client.getUserIdLocalpart(),
|
userName: client.getUserIdLocalpart(),
|
||||||
@@ -395,7 +226,6 @@ export function ClientProvider({ children }) {
|
|||||||
loading: false,
|
loading: false,
|
||||||
isAuthenticated: true,
|
isAuthenticated: true,
|
||||||
isPasswordlessUser: !!session.passwordlessUser,
|
isPasswordlessUser: !!session.passwordlessUser,
|
||||||
isGuest: false,
|
|
||||||
userName: client.getUserIdLocalpart(),
|
userName: client.getUserIdLocalpart(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -406,7 +236,6 @@ export function ClientProvider({ children }) {
|
|||||||
loading: false,
|
loading: false,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
isPasswordlessUser: false,
|
isPasswordlessUser: false,
|
||||||
isGuest: false,
|
|
||||||
userName: null,
|
userName: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -422,11 +251,7 @@ export function ClientProvider({ children }) {
|
|||||||
loading,
|
loading,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
isPasswordlessUser,
|
isPasswordlessUser,
|
||||||
isGuest,
|
|
||||||
client,
|
client,
|
||||||
login,
|
|
||||||
registerGuest,
|
|
||||||
register,
|
|
||||||
changePassword,
|
changePassword,
|
||||||
logout,
|
logout,
|
||||||
userName,
|
userName,
|
||||||
@@ -436,11 +261,7 @@ export function ClientProvider({ children }) {
|
|||||||
loading,
|
loading,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
isPasswordlessUser,
|
isPasswordlessUser,
|
||||||
isGuest,
|
|
||||||
client,
|
client,
|
||||||
login,
|
|
||||||
registerGuest,
|
|
||||||
register,
|
|
||||||
changePassword,
|
changePassword,
|
||||||
logout,
|
logout,
|
||||||
userName,
|
userName,
|
||||||
@@ -496,11 +317,6 @@ export async function createRoom(client, name) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.setGuestAccess(room_id, {
|
|
||||||
allowJoin: true,
|
|
||||||
allowRead: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.createGroupCall(
|
await client.createGroupCall(
|
||||||
room_id,
|
room_id,
|
||||||
GroupCallType.Video,
|
GroupCallType.Video,
|
||||||
@@ -747,126 +563,3 @@ export function useProfile(client) {
|
|||||||
|
|
||||||
return { loading, error, displayName, avatarUrl, saveProfile, success };
|
return { loading, error, displayName, avatarUrl, saveProfile, success };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useInteractiveLogin() {
|
|
||||||
const { setClient } = useClient();
|
|
||||||
const [state, setState] = useState({ loading: false });
|
|
||||||
|
|
||||||
const auth = useCallback(async (homeserver, username, password) => {
|
|
||||||
const authClient = matrix.createClient(homeserver);
|
|
||||||
|
|
||||||
const interactiveAuth = new InteractiveAuth({
|
|
||||||
matrixClient: authClient,
|
|
||||||
busyChanged(loading) {
|
|
||||||
setState((prev) => ({ ...prev, loading }));
|
|
||||||
},
|
|
||||||
async doRequest(auth, _background) {
|
|
||||||
return authClient.login("m.login.password", {
|
|
||||||
identifier: {
|
|
||||||
type: "m.id.user",
|
|
||||||
user: username,
|
|
||||||
},
|
|
||||||
password,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
stateUpdated(nextStage, status) {
|
|
||||||
console.log({ nextStage, status });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { user_id, access_token, device_id } =
|
|
||||||
await interactiveAuth.attemptAuth();
|
|
||||||
|
|
||||||
const client = await initClient({
|
|
||||||
baseUrl: defaultHomeserver,
|
|
||||||
accessToken: access_token,
|
|
||||||
userId: user_id,
|
|
||||||
deviceId: device_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
setClient(client, { user_id, access_token, device_id });
|
|
||||||
|
|
||||||
return client;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return [state, auth];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useInteractiveRegistration() {
|
|
||||||
const { setClient } = useClient();
|
|
||||||
const [state, setState] = useState({ privacyPolicyUrl: "#", loading: false });
|
|
||||||
|
|
||||||
const authClientRef = useRef();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
authClientRef.current = matrix.createClient(defaultHomeserver);
|
|
||||||
|
|
||||||
authClientRef.current.registerRequest({}).catch((error) => {
|
|
||||||
const privacyPolicyUrl =
|
|
||||||
error.data?.params["m.login.terms"]?.policies?.privacy_policy?.en?.url;
|
|
||||||
|
|
||||||
const recaptchaKey = error.data?.params["m.login.recaptcha"]?.public_key;
|
|
||||||
|
|
||||||
if (privacyPolicyUrl || recaptchaKey) {
|
|
||||||
setState((prev) => ({ ...prev, privacyPolicyUrl, recaptchaKey }));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const register = useCallback(
|
|
||||||
async (username, password, recaptchaResponse, passwordlessUser) => {
|
|
||||||
const interactiveAuth = new InteractiveAuth({
|
|
||||||
matrixClient: authClientRef.current,
|
|
||||||
busyChanged(loading) {
|
|
||||||
setState((prev) => ({ ...prev, loading }));
|
|
||||||
},
|
|
||||||
async doRequest(auth, _background) {
|
|
||||||
return authClientRef.current.registerRequest({
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
auth: auth || undefined,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
stateUpdated(nextStage, status) {
|
|
||||||
if (status.error) {
|
|
||||||
throw new Error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextStage === "m.login.terms") {
|
|
||||||
interactiveAuth.submitAuthDict({
|
|
||||||
type: "m.login.terms",
|
|
||||||
});
|
|
||||||
} else if (nextStage === "m.login.recaptcha") {
|
|
||||||
interactiveAuth.submitAuthDict({
|
|
||||||
type: "m.login.recaptcha",
|
|
||||||
response: recaptchaResponse,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { user_id, access_token, device_id } =
|
|
||||||
await interactiveAuth.attemptAuth();
|
|
||||||
|
|
||||||
const client = await initClient({
|
|
||||||
baseUrl: defaultHomeserver,
|
|
||||||
accessToken: access_token,
|
|
||||||
userId: user_id,
|
|
||||||
deviceId: device_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
const session = { user_id, device_id, access_token, passwordlessUser };
|
|
||||||
|
|
||||||
if (passwordlessUser) {
|
|
||||||
session.tempPassword = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
setClient(client, session);
|
|
||||||
|
|
||||||
return client;
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
return [state, register];
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ import { Button } from "../button";
|
|||||||
import {
|
import {
|
||||||
defaultHomeserver,
|
defaultHomeserver,
|
||||||
defaultHomeserverHost,
|
defaultHomeserverHost,
|
||||||
useInteractiveLogin,
|
|
||||||
} from "../ConferenceCallManagerHooks";
|
} from "../ConferenceCallManagerHooks";
|
||||||
import styles from "./LoginPage.module.css";
|
import styles from "./LoginPage.module.css";
|
||||||
|
import { useInteractiveLogin } from "./useInteractiveLogin";
|
||||||
|
|
||||||
export function LoginPage() {
|
export function LoginPage() {
|
||||||
const [_, login] = useInteractiveLogin();
|
const [_, login] = useInteractiveLogin();
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ import { Button } from "../button";
|
|||||||
import {
|
import {
|
||||||
useClient,
|
useClient,
|
||||||
defaultHomeserverHost,
|
defaultHomeserverHost,
|
||||||
useInteractiveRegistration,
|
|
||||||
} from "../ConferenceCallManagerHooks";
|
} from "../ConferenceCallManagerHooks";
|
||||||
|
import { useInteractiveRegistration } from "./useInteractiveRegistration";
|
||||||
import styles from "./LoginPage.module.css";
|
import styles from "./LoginPage.module.css";
|
||||||
import { ReactComponent as Logo } from "../icons/LogoLarge.svg";
|
import { ReactComponent as Logo } from "../icons/LogoLarge.svg";
|
||||||
import { LoadingView } from "../FullScreenView";
|
import { LoadingView } from "../FullScreenView";
|
||||||
|
|||||||
48
src/auth/useInteractiveLogin.js
Normal file
48
src/auth/useInteractiveLogin.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import matrix, { InteractiveAuth } from "matrix-js-sdk/src/browser-index";
|
||||||
|
import { useState, useCallback } from "react";
|
||||||
|
import {
|
||||||
|
useClient,
|
||||||
|
initClient,
|
||||||
|
defaultHomeserver,
|
||||||
|
} from "../ConferenceCallManagerHooks";
|
||||||
|
|
||||||
|
export function useInteractiveLogin() {
|
||||||
|
const { setClient } = useClient();
|
||||||
|
const [state, setState] = useState({ loading: false });
|
||||||
|
|
||||||
|
const auth = useCallback(async (homeserver, username, password) => {
|
||||||
|
const authClient = matrix.createClient(homeserver);
|
||||||
|
|
||||||
|
const interactiveAuth = new InteractiveAuth({
|
||||||
|
matrixClient: authClient,
|
||||||
|
busyChanged(loading) {
|
||||||
|
setState((prev) => ({ ...prev, loading }));
|
||||||
|
},
|
||||||
|
async doRequest(_auth, _background) {
|
||||||
|
return authClient.login("m.login.password", {
|
||||||
|
identifier: {
|
||||||
|
type: "m.id.user",
|
||||||
|
user: username,
|
||||||
|
},
|
||||||
|
password,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { user_id, access_token, device_id } =
|
||||||
|
await interactiveAuth.attemptAuth();
|
||||||
|
|
||||||
|
const client = await initClient({
|
||||||
|
baseUrl: defaultHomeserver,
|
||||||
|
accessToken: access_token,
|
||||||
|
userId: user_id,
|
||||||
|
deviceId: device_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
setClient(client, { user_id, access_token, device_id });
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return [state, auth];
|
||||||
|
}
|
||||||
86
src/auth/useInteractiveRegistration.js
Normal file
86
src/auth/useInteractiveRegistration.js
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import matrix, { InteractiveAuth } from "matrix-js-sdk/src/browser-index";
|
||||||
|
import { useState, useEffect, useCallback, useRef } from "react";
|
||||||
|
import {
|
||||||
|
useClient,
|
||||||
|
initClient,
|
||||||
|
defaultHomeserver,
|
||||||
|
} from "../ConferenceCallManagerHooks";
|
||||||
|
|
||||||
|
export function useInteractiveRegistration() {
|
||||||
|
const { setClient } = useClient();
|
||||||
|
const [state, setState] = useState({ privacyPolicyUrl: "#", loading: false });
|
||||||
|
|
||||||
|
const authClientRef = useRef();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
authClientRef.current = matrix.createClient(defaultHomeserver);
|
||||||
|
|
||||||
|
authClientRef.current.registerRequest({}).catch((error) => {
|
||||||
|
const privacyPolicyUrl =
|
||||||
|
error.data?.params["m.login.terms"]?.policies?.privacy_policy?.en?.url;
|
||||||
|
|
||||||
|
const recaptchaKey = error.data?.params["m.login.recaptcha"]?.public_key;
|
||||||
|
|
||||||
|
if (privacyPolicyUrl || recaptchaKey) {
|
||||||
|
setState((prev) => ({ ...prev, privacyPolicyUrl, recaptchaKey }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const register = useCallback(
|
||||||
|
async (username, password, recaptchaResponse, passwordlessUser) => {
|
||||||
|
const interactiveAuth = new InteractiveAuth({
|
||||||
|
matrixClient: authClientRef.current,
|
||||||
|
busyChanged(loading) {
|
||||||
|
setState((prev) => ({ ...prev, loading }));
|
||||||
|
},
|
||||||
|
async doRequest(auth, _background) {
|
||||||
|
return authClientRef.current.registerRequest({
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
auth: auth || undefined,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
stateUpdated(nextStage, status) {
|
||||||
|
if (status.error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextStage === "m.login.terms") {
|
||||||
|
interactiveAuth.submitAuthDict({
|
||||||
|
type: "m.login.terms",
|
||||||
|
});
|
||||||
|
} else if (nextStage === "m.login.recaptcha") {
|
||||||
|
interactiveAuth.submitAuthDict({
|
||||||
|
type: "m.login.recaptcha",
|
||||||
|
response: recaptchaResponse,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { user_id, access_token, device_id } =
|
||||||
|
await interactiveAuth.attemptAuth();
|
||||||
|
|
||||||
|
const client = await initClient({
|
||||||
|
baseUrl: defaultHomeserver,
|
||||||
|
accessToken: access_token,
|
||||||
|
userId: user_id,
|
||||||
|
deviceId: device_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const session = { user_id, device_id, access_token, passwordlessUser };
|
||||||
|
|
||||||
|
if (passwordlessUser) {
|
||||||
|
session.tempPassword = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
setClient(client, session);
|
||||||
|
|
||||||
|
return client;
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
return [state, register];
|
||||||
|
}
|
||||||
@@ -7,9 +7,9 @@ import { Button } from "../button";
|
|||||||
import { randomString } from "matrix-js-sdk/src/randomstring";
|
import { randomString } from "matrix-js-sdk/src/randomstring";
|
||||||
import {
|
import {
|
||||||
createRoom,
|
createRoom,
|
||||||
useInteractiveRegistration,
|
|
||||||
roomAliasFromRoomName,
|
roomAliasFromRoomName,
|
||||||
} from "../ConferenceCallManagerHooks";
|
} from "../ConferenceCallManagerHooks";
|
||||||
|
import { useInteractiveRegistration } from "../auth/useInteractiveRegistration";
|
||||||
import { useModalTriggerState } from "../Modal";
|
import { useModalTriggerState } from "../Modal";
|
||||||
import { JoinExistingCallModal } from "../JoinExistingCallModal";
|
import { JoinExistingCallModal } from "../JoinExistingCallModal";
|
||||||
import { useRecaptcha } from "../auth/useRecaptcha";
|
import { useRecaptcha } from "../auth/useRecaptcha";
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { useLocation } from "react-router-dom";
|
|||||||
import { useRecaptcha } from "../auth/useRecaptcha";
|
import { useRecaptcha } from "../auth/useRecaptcha";
|
||||||
import { FieldRow, InputField, ErrorMessage } from "../Input";
|
import { FieldRow, InputField, ErrorMessage } from "../Input";
|
||||||
import { randomString } from "matrix-js-sdk/src/randomstring";
|
import { randomString } from "matrix-js-sdk/src/randomstring";
|
||||||
import { useInteractiveRegistration } from "../ConferenceCallManagerHooks";
|
import { useInteractiveRegistration } from "../auth/useInteractiveRegistration";
|
||||||
import { Form } from "../form/Form";
|
import { Form } from "../form/Form";
|
||||||
|
|
||||||
export function RoomAuthView() {
|
export function RoomAuthView() {
|
||||||
|
|||||||
Reference in New Issue
Block a user