import { Button, Classes, FormGroup, H1, H2, Icon, InputGroup, Intent } from "@blueprintjs/core"; import { IconNames } from "@blueprintjs/icons"; import React from "react"; import { Redirect } from "react-router"; import styled from "styled-components"; import AppToaster from "../../toaster"; import { getAuthToken, getFromApi, postToApi } from "../../util"; import { Page } from "../atoms"; import { ErrorState } from "../molecules"; interface FormContainerProps { error: boolean; } const FormContainer = styled.div` ${(props) => (props.error ? "margin: 20px auto 0 auto;" : "margin-top: 20px;")} `; const LoginTypeContainer = styled.div` display: flex; width: 100%; `; const LoginTypeButton = styled(Button)` flex: 1; margin: 0 10px; `; const PostLoginContainer = styled.div` align-self: center; text-align: center; margin-top: 20px; `; const StyledIcon = styled(Icon)` margin-bottom: 10px; `; interface LoginTypes { domain: string; email?: string; fediverseAccount?: string; } interface LoginScreenState { domain: string; isGettingLoginTypes: boolean; isSendingLoginRequest: boolean; loginTypes?: LoginTypes; selectedLoginType?: "email" | "fediverseAccount"; error: boolean; } class LoginScreen extends React.PureComponent<{}, LoginScreenState> { public constructor(props: any) { super(props); this.state = { domain: "", error: false, isGettingLoginTypes: false, isSendingLoginRequest: false, }; } public render() { const authToken = getAuthToken(); if (authToken) { return ; } const { error, loginTypes, isSendingLoginRequest, selectedLoginType } = this.state; let content; if (error) { content = ( ); } else if (!!selectedLoginType && !isSendingLoginRequest) { content = this.renderPostLogin(); } else if (loginTypes) { content = this.renderChooseLoginType(); } else { content = this.renderChooseInstance(); } return (

Login

You must be the instance admin to manage how index.community interacts with your instance.

It's currently only possible to administrate Mastodon and Pleroma instances. If you want to login with a direct message, your instance must federate with social.inex.rocks and vice versa.

If you run another server type, you can manually opt in or out by writing to{" "} @indexCommunity.

{content}
); } private renderChooseInstance = () => { const { isGettingLoginTypes } = this.state; const onButtonClick = () => this.getLoginTypes(); return (
} placeholder="mastodon.social" />
); }; private renderChooseLoginType = () => { const { loginTypes, isSendingLoginRequest } = this.state; if (!loginTypes) { return; } const loginWithEmail = () => this.login("email"); const loginWithDm = () => this.login("fediverseAccount"); return ( <>

Choose an authentication method

{loginTypes.email && ( {`Email ${loginTypes.email}`} )} {loginTypes.fediverseAccount && ( {`DM ${loginTypes.fediverseAccount}`} )} ); }; private renderPostLogin = () => { const { selectedLoginType, loginTypes } = this.state; let message; if (selectedLoginType === "email") { message = `Check ${loginTypes!.email} for a login link`; } else { message = `Check ${loginTypes!.fediverseAccount}'s DMs for a login link.`; } return (

{message}

); }; private updateDomainInState = (event: React.ChangeEvent) => { this.setState({ domain: event.target.value }); }; private getLoginTypes = (e?: React.FormEvent) => { if (e) { e.preventDefault(); } this.setState({ isGettingLoginTypes: true }); let { domain } = this.state; if (domain.startsWith("https://")) { domain = domain.slice(8); } getFromApi(`admin/login/${domain.trim()}`) .then((response) => { if (response.error) { // Go to catch() below throw new Error(response.error); } else { this.setState({ loginTypes: response, isGettingLoginTypes: false }); } }) .catch((err: Error) => { AppToaster.show({ icon: IconNames.ERROR, intent: Intent.DANGER, message: err.message, }); this.setState({ isGettingLoginTypes: false }); }); }; private login = (type: "email" | "fediverseAccount") => { this.setState({ isSendingLoginRequest: true, selectedLoginType: type }); postToApi("admin/login", { domain: this.state.loginTypes!.domain, type }) .then((response) => { if ("error" in response || "errors" in response) { // Go to catch() below throw new Error(); } else { this.setState({ isSendingLoginRequest: false }); } }) .catch(() => this.setState({ isSendingLoginRequest: false, error: true })); }; } export default LoginScreen;