mirror of
https://github.com/vector-im/element-call.git
synced 2026-02-23 05:07:03 +00:00
The one place where we should log out of PostHog and reset our analytics ID is when the user is logging out. This matches the behavior in Element Web and makes sense, I think, because logging out is essentially a request for the app to forget who you are. This means we should also start analytics at the point of logging in / reauthenticating. I noticed while making this change that there was an unused branch in setClient, so I cleaned it up rather than making myself update it.
146 lines
4.9 KiB
TypeScript
146 lines
4.9 KiB
TypeScript
/*
|
|
Copyright 2021-2024 New Vector Ltd.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE in the repository root for full details.
|
|
*/
|
|
|
|
import { type FC, type FormEvent, useCallback, useRef, useState } from "react";
|
|
import { useNavigate, useLocation } from "react-router-dom";
|
|
import { Trans, useTranslation } from "react-i18next";
|
|
import { Button } from "@vector-im/compound-web";
|
|
|
|
import Logo from "../icons/LogoLarge.svg?react";
|
|
import { useClient } from "../ClientContext";
|
|
import { FieldRow, InputField, ErrorMessage } from "../input/Input";
|
|
import styles from "./LoginPage.module.css";
|
|
import { useInteractiveLogin } from "./useInteractiveLogin";
|
|
import { usePageTitle } from "../usePageTitle";
|
|
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
|
import { Config } from "../config/Config";
|
|
import { Link } from "../button/Link";
|
|
|
|
export const LoginPage: FC = () => {
|
|
const { t } = useTranslation();
|
|
usePageTitle(t("login_title"));
|
|
|
|
const { client, setClient } = useClient();
|
|
const login = useInteractiveLogin(client);
|
|
const homeserver = Config.defaultHomeserverUrl(); // TODO: Make this configurable
|
|
const usernameRef = useRef<HTMLInputElement>(null);
|
|
const passwordRef = useRef<HTMLInputElement>(null);
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<Error>();
|
|
|
|
// TODO: Handle hitting login page with authenticated client
|
|
|
|
const onSubmitLoginForm = useCallback(
|
|
(e: FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
setLoading(true);
|
|
|
|
if (!homeserver || !usernameRef.current || !passwordRef.current) {
|
|
setError(Error("Login parameters are undefined"));
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
|
|
login(homeserver, usernameRef.current.value, passwordRef.current.value)
|
|
.then(async ([client, session]) => {
|
|
if (!setClient) {
|
|
return;
|
|
}
|
|
|
|
setClient(client, session);
|
|
|
|
const locationState = location.state;
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
if (locationState && locationState.from) {
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
await navigate(locationState.from);
|
|
} else {
|
|
await navigate("/");
|
|
}
|
|
PosthogAnalytics.instance.eventLogin.track();
|
|
})
|
|
.catch((error) => {
|
|
setError(error);
|
|
setLoading(false);
|
|
});
|
|
},
|
|
[login, location, navigate, homeserver, setClient],
|
|
);
|
|
// we need to limit the length of the homserver name to not cover the whole loginview input with the string.
|
|
let shortendHomeserverName = Config.defaultServerName()?.slice(0, 25);
|
|
shortendHomeserverName =
|
|
shortendHomeserverName?.length !== Config.defaultServerName()?.length
|
|
? shortendHomeserverName + "..."
|
|
: shortendHomeserverName;
|
|
return (
|
|
<>
|
|
<div className={styles.container}>
|
|
<div className={styles.content}>
|
|
<div className={styles.formContainer}>
|
|
<Logo width="auto" height="auto" className={styles.logo} />
|
|
|
|
<h2>{t("log_in")}</h2>
|
|
<h4>{t("login_subheading")}</h4>
|
|
<form onSubmit={onSubmitLoginForm}>
|
|
<FieldRow>
|
|
<InputField
|
|
type="text"
|
|
ref={usernameRef}
|
|
placeholder={t("common.username")}
|
|
label={t("common.username")}
|
|
autoCorrect="off"
|
|
autoCapitalize="none"
|
|
prefix="@"
|
|
suffix={`:${shortendHomeserverName}`}
|
|
data-testid="login_username"
|
|
/>
|
|
</FieldRow>
|
|
<FieldRow>
|
|
<InputField
|
|
type="password"
|
|
ref={passwordRef}
|
|
placeholder={t("common.password")}
|
|
label={t("common.password")}
|
|
data-testid="login_password"
|
|
/>
|
|
</FieldRow>
|
|
{error && (
|
|
<FieldRow>
|
|
<ErrorMessage error={error} />
|
|
</FieldRow>
|
|
)}
|
|
<FieldRow>
|
|
<Button
|
|
type="submit"
|
|
disabled={loading}
|
|
data-testid="login_login"
|
|
>
|
|
{loading ? t("logging_in") : t("login_title")}
|
|
</Button>
|
|
</FieldRow>
|
|
</form>
|
|
</div>
|
|
<div className={styles.authLinks}>
|
|
<p>{t("login_auth_links_prompt")}</p>
|
|
<p>
|
|
<Trans i18nKey="login_auth_links">
|
|
<Link to="/register">Create an account</Link>
|
|
{" Or "}
|
|
<Link to="/">Access as a guest</Link>
|
|
</Trans>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|