import { Component, linkEvent } from "inferno"; import { GetSiteResponse, Login as LoginI, LoginResponse, PasswordReset, UserOperation, wsJsonToRes, wsUserOp, } from "lemmy-js-client"; import { Subscription } from "rxjs"; import { i18n } from "../../i18next"; import { UserService, WebSocketService } from "../../services"; import { isBrowser, setIsoData, toast, validEmail, wsClient, wsSubscribe, } from "../../utils"; import { HtmlTags } from "../common/html-tags"; import { Spinner } from "../common/icon"; interface State { form: { username_or_email?: string; password?: string; totp_2fa_token?: string; }; loginLoading: boolean; showTotp: boolean; siteRes: GetSiteResponse; } export class Login extends Component { private isoData = setIsoData(this.context); private subscription?: Subscription; state: State = { form: {}, loginLoading: false, showTotp: false, siteRes: this.isoData.site_res, }; constructor(props: any, context: any) { super(props, context); this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); if (isBrowser()) { WebSocketService.Instance.send(wsClient.getCaptcha()); } } componentDidMount() { // Navigate to home if already logged in if (UserService.Instance.myUserInfo) { this.context.router.history.push("/"); } } componentWillUnmount() { if (isBrowser()) { this.subscription?.unsubscribe(); } } get documentTitle(): string { return `${i18n.t("login")} - ${this.state.siteRes.site_view.site.name}`; } get isLemmyMl(): boolean { return isBrowser() && window.location.hostname == "lemmy.ml"; } render() { return (
{this.loginForm()}
); } loginForm() { return (
{i18n.t("login")}
{this.state.showTotp && (
)}
); } handleLoginSubmit(i: Login, event: any) { event.preventDefault(); i.setState({ loginLoading: true }); let lForm = i.state.form; let username_or_email = lForm.username_or_email; let password = lForm.password; let totp_2fa_token = lForm.totp_2fa_token; if (username_or_email && password) { let form: LoginI = { username_or_email, password, totp_2fa_token, }; WebSocketService.Instance.send(wsClient.login(form)); } } handleLoginUsernameChange(i: Login, event: any) { i.state.form.username_or_email = event.target.value; i.setState(i.state); } handleLoginTotpChange(i: Login, event: any) { i.state.form.totp_2fa_token = event.target.value; i.setState(i.state); } handleLoginPasswordChange(i: Login, event: any) { i.state.form.password = event.target.value; i.setState(i.state); } handlePasswordReset(i: Login, event: any) { event.preventDefault(); let email = i.state.form.username_or_email; if (email) { let resetForm: PasswordReset = { email }; WebSocketService.Instance.send(wsClient.passwordReset(resetForm)); } } parseMessage(msg: any) { let op = wsUserOp(msg); console.log(msg); if (msg.error) { // If the error comes back that the token is missing, show the TOTP field if (msg.error == "missing_totp_token") { this.setState({ showTotp: true, loginLoading: false }); toast(i18n.t("enter_two_factor_code")); return; } else { toast(i18n.t(msg.error), "danger"); this.setState({ form: {}, loginLoading: false }); return; } } else { if (op == UserOperation.Login) { let data = wsJsonToRes(msg); UserService.Instance.login(data); this.props.history.push("/"); location.reload(); } else if (op == UserOperation.PasswordReset) { toast(i18n.t("reset_password_mail_sent")); } else if (op == UserOperation.GetSite) { let data = wsJsonToRes(msg); this.setState({ siteRes: data }); } } } }