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 fediverse.space

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;