import React, { useCallback, useEffect } from 'react';
import { Box, Header, Scroll, Spinner, Text, color } from 'folds';
import {
Outlet,
generatePath,
matchPath,
useLocation,
useNavigate,
useParams,
} from 'react-router-dom';
import classNames from 'classnames';
import { AuthFooter } from './AuthFooter';
import * as css from './styles.css';
import * as PatternsCss from '../../styles/Patterns.css';
import {
clientAllowedServer,
clientDefaultServer,
useClientConfig,
} from '../../hooks/useClientConfig';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH } from '../paths';
import CinnySVG from '../../../../public/res/svg/cinny.svg';
import { ServerPicker } from './ServerPicker';
import { AutoDiscoveryAction, autoDiscovery } from '../../cs-api';
import { SpecVersionsLoader } from '../../components/SpecVersionsLoader';
import { SpecVersionsProvider } from '../../hooks/useSpecVersions';
import { AutoDiscoveryInfoProvider } from '../../hooks/useAutoDiscoveryInfo';
import { AuthFlowsLoader } from '../../components/AuthFlowsLoader';
import { AuthFlowsProvider } from '../../hooks/useAuthFlows';
import { AuthServerProvider } from '../../hooks/useAuthServer';
import { tryDecodeURIComponent } from '../../utils/dom';
const currentAuthPath = (pathname: string): string => {
if (matchPath(LOGIN_PATH, pathname)) {
return LOGIN_PATH;
}
if (matchPath(RESET_PASSWORD_PATH, pathname)) {
return RESET_PASSWORD_PATH;
}
if (matchPath(REGISTER_PATH, pathname)) {
return REGISTER_PATH;
}
return LOGIN_PATH;
};
function AuthLayoutLoading({ message }: { message: string }) {
return (
{message}
);
}
function AuthLayoutError({ message }: { message: string }) {
return (
{message}
);
}
export function AuthLayout() {
const navigate = useNavigate();
const location = useLocation();
const { server: urlEncodedServer } = useParams();
const clientConfig = useClientConfig();
const defaultServer = clientDefaultServer(clientConfig);
let server: string = urlEncodedServer ? tryDecodeURIComponent(urlEncodedServer) : defaultServer;
if (!clientAllowedServer(clientConfig, server)) {
server = defaultServer;
}
const [discoveryState, discoverServer] = useAsyncCallback(
useCallback(async (serverName: string) => {
const response = await autoDiscovery(fetch, serverName);
return {
serverName,
response,
};
}, [])
);
useEffect(() => {
if (server) discoverServer(server);
}, [discoverServer, server]);
// if server is mismatches with path server, update path
useEffect(() => {
if (!urlEncodedServer || tryDecodeURIComponent(urlEncodedServer) !== server) {
navigate(
generatePath(currentAuthPath(location.pathname), {
server: encodeURIComponent(server),
}),
{ replace: true }
);
}
}, [urlEncodedServer, navigate, location, server]);
const selectServer = useCallback(
(newServer: string) => {
if (newServer === server) {
if (discoveryState.status === AsyncStatus.Loading) return;
discoverServer(server);
return;
}
navigate(
generatePath(currentAuthPath(location.pathname), { server: encodeURIComponent(newServer) })
);
},
[navigate, location, discoveryState, server, discoverServer]
);
const [autoDiscoveryError, autoDiscoveryInfo] =
discoveryState.status === AsyncStatus.Success ? discoveryState.data.response : [];
return (
Cinny
Homeserver
{discoveryState.status === AsyncStatus.Loading && (
)}
{discoveryState.status === AsyncStatus.Error && (
)}
{autoDiscoveryError?.action === AutoDiscoveryAction.FAIL_PROMPT && (
)}
{autoDiscoveryError?.action === AutoDiscoveryAction.FAIL_ERROR && (
)}
{discoveryState.status === AsyncStatus.Success && autoDiscoveryInfo && (
(
)}
error={() => (
)}
>
{(specVersions) => (
(
)}
error={() => (
)}
>
{(authFlows) => (
)}
)}
)}
);
}