import React, { FormEventHandler, useCallback, useState } from 'react';
import {
Box,
Button,
Header,
Icon,
IconButton,
Icons,
Input,
Menu,
Overlay,
OverlayBackdrop,
OverlayCenter,
PopOut,
Spinner,
Text,
config,
} from 'folds';
import FocusTrap from 'focus-trap-react';
import { Link } from 'react-router-dom';
import { MatrixError } from 'matrix-js-sdk';
import { getMxIdLocalPart, getMxIdServer, isUserId } from '../../../utils/matrix';
import { EMAIL_REGEX } from '../../../utils/regex';
import { useAutoDiscoveryInfo } from '../../../hooks/useAutoDiscoveryInfo';
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
import { useAuthServer } from '../../../hooks/useAuthServer';
import { useClientConfig } from '../../../hooks/useClientConfig';
import {
CustomLoginResponse,
LoginError,
factoryGetBaseUrl,
login,
useLoginComplete,
} from './loginUtil';
import { PasswordInput } from '../../../components/password-input/PasswordInput';
import { FieldError } from '../FiledError';
import { getResetPasswordPath } from '../../pathUtils';
function UsernameHint({ server }: { server: string }) {
const [open, setOpen] = useState(false);
return (
setOpen(false),
clickOutsideDeactivates: true,
}}
>
}
>
{(targetRef) => (
setOpen(true)}
ref={targetRef}
type="button"
variant="Background"
size="300"
radii="300"
aria-pressed={open}
>
)}
);
}
type PasswordLoginFormProps = {
defaultUsername?: string;
defaultEmail?: string;
};
export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLoginFormProps) {
const server = useAuthServer();
const clientConfig = useClientConfig();
const serverDiscovery = useAutoDiscoveryInfo();
const baseUrl = serverDiscovery['m.homeserver'].base_url;
const [loginState, startLogin] = useAsyncCallback<
CustomLoginResponse,
MatrixError,
Parameters
>(useCallback(login, []));
useLoginComplete(loginState.status === AsyncStatus.Success ? loginState.data : undefined);
const handleUsernameLogin = (username: string, password: string) => {
startLogin(baseUrl, {
type: 'm.login.password',
identifier: {
type: 'm.id.user',
user: username,
},
password,
initial_device_display_name: 'Cinny Web',
});
};
const handleMxIdLogin = async (mxId: string, password: string) => {
const mxIdServer = getMxIdServer(mxId);
const mxIdUsername = getMxIdLocalPart(mxId);
if (!mxIdServer || !mxIdUsername) return;
const getBaseUrl = factoryGetBaseUrl(clientConfig, mxIdServer);
startLogin(getBaseUrl, {
type: 'm.login.password',
identifier: {
type: 'm.id.user',
user: mxIdUsername,
},
password,
initial_device_display_name: 'Cinny Web',
});
};
const handleEmailLogin = (email: string, password: string) => {
startLogin(baseUrl, {
type: 'm.login.password',
identifier: {
type: 'm.id.thirdparty',
medium: 'email',
address: email,
},
password,
initial_device_display_name: 'Cinny Web',
});
};
const handleSubmit: FormEventHandler = (evt) => {
evt.preventDefault();
const { usernameInput, passwordInput } = evt.target as HTMLFormElement & {
usernameInput: HTMLInputElement;
passwordInput: HTMLInputElement;
};
const username = usernameInput.value.trim();
const password = passwordInput.value;
if (!username) {
usernameInput.focus();
return;
}
if (!password) {
passwordInput.focus();
return;
}
if (isUserId(username)) {
handleMxIdLogin(username, password);
return;
}
if (EMAIL_REGEX.test(username)) {
handleEmailLogin(username, password);
return;
}
handleUsernameLogin(username, password);
};
return (
Username
}
/>
{loginState.status === AsyncStatus.Error && (
<>
{loginState.error.errcode === LoginError.ServerNotAllowed && (
)}
{loginState.error.errcode === LoginError.InvalidServer && (
)}
>
)}
Password
{loginState.status === AsyncStatus.Error && (
<>
{loginState.error.errcode === LoginError.Forbidden && (
)}
{loginState.error.errcode === LoginError.UserDeactivated && (
)}
{loginState.error.errcode === LoginError.InvalidRequest && (
)}
{loginState.error.errcode === LoginError.RateLimited && (
)}
{loginState.error.errcode === LoginError.Unknown && (
)}
>
)}
Forget Password?
}
>
);
}