diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index 6acb02f..cb6ee98 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -23,6 +23,7 @@ import { useTranslate, PasswordInput, TextInput, + SelectInput, useLocales, } from "react-admin"; import { useFormContext } from "react-hook-form"; @@ -51,16 +52,31 @@ const LoginPage = () => { restrictBaseUrl.length > 0 && restrictBaseUrl[0] !== "" && restrictBaseUrl[0] !== null; + const baseUrlChoices = allowMultipleBaseUrls ? restrictBaseUrl.map(url => ({ id: url, name: url })) : []; const allowAnyBaseUrl = !(allowSingleBaseUrl || allowMultipleBaseUrls); + const localStorageBaseUrl = localStorage.getItem("base_url"); + let base_url = allowSingleBaseUrl ? restrictBaseUrl : localStorageBaseUrl; + if (allowMultipleBaseUrls && localStorageBaseUrl && !restrictBaseUrl.includes(localStorageBaseUrl)) { + // don't set base_url if it is not in the restrictBaseUrl array + base_url = null; + } const [loading, setLoading] = useState(false); const [supportPassAuth, setSupportPassAuth] = useState(true); const [locale, setLocale] = useLocaleState(); const locales = useLocales(); const translate = useTranslate(); - const base_url = allowSingleBaseUrl ? restrictBaseUrl : localStorage.getItem("base_url"); + const [ssoBaseUrl, setSSOBaseUrl] = useState(""); const loginToken = new URLSearchParams(window.location.search).get("loginToken"); const [loginMethod, setLoginMethod] = useState("credentials"); + const [serverVersion, setServerVersion] = useState(""); + const [matrixVersions, setMatrixVersions] = useState(""); + + useEffect(() => { + if (base_url) { + checkServerInfo(base_url); + } + }, []); useEffect(() => { if (!loginToken) { @@ -133,66 +149,77 @@ const LoginPage = () => { window.location.href = ssoFullUrl; }; + const checkServerInfo = async (url: string) => { + if (!isValidBaseUrl(url)) { + setServerVersion(""); + setMatrixVersions(""); + setSupportPassAuth(false); + setSSOBaseUrl(""); + return; + } + + try { + const serverVersion = await getServerVersion(url); + setServerVersion(`${translate("synapseadmin.auth.server_version")} ${serverVersion}`); + } catch (error) { + setServerVersion(""); + } + + try { + const features = await getSupportedFeatures(url); + setMatrixVersions(`${translate("synapseadmin.auth.supports_specs")} ${features.versions.join(", ")}`); + } catch (error) { + setMatrixVersions(""); + } + + // Set SSO Url + try { + const loginFlows = await getSupportedLoginFlows(url); + const supportPass = loginFlows.find(f => f.type === "m.login.password") !== undefined; + const supportSSO = loginFlows.find(f => f.type === "m.login.sso") !== undefined; + setSupportPassAuth(supportPass); + setSSOBaseUrl(supportSSO ? url : ""); + } catch (error) { + setSupportPassAuth(false); + setSSOBaseUrl(""); + } + }; + + const UserData = ({ formData }) => { const form = useFormContext(); - const [serverVersion, setServerVersion] = useState(""); - const [matrixVersions, setMatrixVersions] = useState(""); - const handleUsernameChange = () => { + const handleUsernameChange = async () => { if (formData.base_url || allowSingleBaseUrl) { return; } // check if username is a full qualified userId then set base_url accordingly const domain = splitMxid(formData.username)?.domain; if (domain) { - getWellKnownUrl(domain).then(url => { + const url = await getWellKnownUrl(domain); if (allowAnyBaseUrl || (allowMultipleBaseUrls && restrictBaseUrl.includes(url))) { form.setValue("base_url", url, { shouldValidate: true, shouldDirty: true, }); - checkServerInfo(url); - } - }); + checkServerInfo(url); + } } }; - const checkServerInfo = (url: string) => { - if (!isValidBaseUrl(url)) return; + const handleBaseUrlBlurOrChange = (event) => { + // Get the value either from the event (onChange) or from formData (onBlur) + const value = event?.target?.value || formData.base_url; - getServerVersion(url) - .then(serverVersion => setServerVersion(`${translate("synapseadmin.auth.server_version")} ${serverVersion}`)) - .catch(() => setServerVersion("")); + if (!value) { + return; + } - getSupportedFeatures(url) - .then(features => - setMatrixVersions(`${translate("synapseadmin.auth.supports_specs")} ${features.versions.join(", ")}`) - ) - .catch(() => setMatrixVersions("")); - - // Set SSO Url - getSupportedLoginFlows(url) - .then(loginFlows => { - const supportPass = loginFlows.find(f => f.type === "m.login.password") !== undefined; - const supportSSO = loginFlows.find(f => f.type === "m.login.sso") !== undefined; - setSupportPassAuth(supportPass); - setSSOBaseUrl(supportSSO ? url : ""); - }) - .catch(() => setSSOBaseUrl("")); - }; - - const handleBaseUrlBlur = () => { - // Trigger validation only when user finishes typing + // Trigger validation only when user finishes typing/selecting form.trigger("base_url"); - checkServerInfo(formData.base_url); + checkServerInfo(value); }; - useEffect(() => { - if (formData.base_url === "" && allowMultipleBaseUrls) { - form.setValue("base_url", restrictBaseUrl[0]); - } - }, [formData.base_url, form]); - useEffect(() => { const params = new URLSearchParams(window.location.search); const hostname = window.location.hostname; @@ -280,24 +307,29 @@ const LoginPage = () => { )} - + )} + {!allowMultipleBaseUrls && ( - {allowMultipleBaseUrls && - restrictBaseUrl.map(url => ( - - {url} - - ))} - + onBlur={handleBaseUrlBlurOrChange} + /> + )} {serverVersion} {matrixVersions}