misc_pterodactyl-panel/resources/scripts/components/auth/LoginCheckpointContainer.tsx

124 lines
4.3 KiB
TypeScript
Raw Normal View History

import React, { useState } from 'react';
import { Link, RouteComponentProps } from 'react-router-dom';
2019-06-22 20:33:11 +00:00
import loginCheckpoint from '@/api/auth/loginCheckpoint';
import { httpErrorToHuman } from '@/api/http';
2019-06-22 20:53:41 +00:00
import LoginFormContainer from '@/components/auth/LoginFormContainer';
2020-04-25 20:01:16 +00:00
import { ActionCreator } from 'easy-peasy';
import { StaticContext } from 'react-router';
2020-04-25 20:01:16 +00:00
import { useFormikContext, withFormik } from 'formik';
import useFlash from '@/plugins/useFlash';
import { FlashStore } from '@/state/flashes';
import Field from '@/components/elements/Field';
import tw from 'twin.macro';
import Button from '@/components/elements/Button';
2020-04-25 20:01:16 +00:00
interface Values {
code: string;
recoveryCode: '',
2020-04-25 20:01:16 +00:00
}
type OwnProps = RouteComponentProps<Record<string, string | undefined>, StaticContext, { token?: string }>
2020-04-25 20:01:16 +00:00
type Props = OwnProps & {
addError: ActionCreator<FlashStore['addError']['payload']>;
clearFlashes: ActionCreator<FlashStore['clearFlashes']['payload']>;
}
2020-04-25 20:01:16 +00:00
const LoginCheckpointContainer = () => {
const { isSubmitting, setFieldValue } = useFormikContext<Values>();
const [ isMissingDevice, setIsMissingDevice ] = useState(false);
2019-06-17 01:07:57 +00:00
2020-04-25 20:01:16 +00:00
return (
<LoginFormContainer title={'Device Checkpoint'} css={tw`w-full flex`}>
<div css={tw`mt-6`}>
2020-04-25 20:01:16 +00:00
<Field
light
name={isMissingDevice ? 'recoveryCode' : 'code'}
title={isMissingDevice ? 'Recovery Code' : 'Authentication Code'}
description={
isMissingDevice
? 'Enter one of the recovery codes generated when you setup 2-Factor authentication on this account in order to continue.'
: 'Enter the two-factor token generated by your device.'
}
type={isMissingDevice ? 'text' : 'number'}
autoFocus
2020-04-25 20:01:16 +00:00
/>
</div>
<div css={tw`mt-6`}>
<Button
size={'xlarge'}
2020-04-25 20:01:16 +00:00
type={'submit'}
disabled={isSubmitting}
isLoading={isSubmitting}
2020-04-25 20:01:16 +00:00
>
Continue
</Button>
2020-04-25 20:01:16 +00:00
</div>
<div css={tw`mt-6 text-center`}>
<span
onClick={() => {
setFieldValue('code', '');
setFieldValue('recoveryCode', '');
setIsMissingDevice(s => !s);
}}
css={tw`cursor-pointer text-xs text-neutral-500 tracking-wide uppercase no-underline hover:text-neutral-700`}
>
{!isMissingDevice ? 'I\'ve Lost My Device' : 'I Have My Device'}
</span>
</div>
<div css={tw`mt-6 text-center`}>
2020-04-25 20:01:16 +00:00
<Link
to={'/auth/login'}
css={tw`text-xs text-neutral-500 tracking-wide uppercase no-underline hover:text-neutral-700`}
2020-04-25 20:01:16 +00:00
>
Return to Login
</Link>
</div>
</LoginFormContainer>
);
};
2019-06-22 20:33:11 +00:00
2020-04-25 20:01:16 +00:00
const EnhancedForm = withFormik<Props, Values>({
handleSubmit: ({ code, recoveryCode }, { setSubmitting, props: { addError, clearFlashes, location } }) => {
clearFlashes();
loginCheckpoint(location.state?.token || '', code, recoveryCode)
.then(response => {
if (response.complete) {
// @ts-ignore
window.location = response.intended || '/';
2020-04-25 20:01:16 +00:00
return;
}
2020-04-25 20:03:37 +00:00
2020-04-25 20:01:16 +00:00
setSubmitting(false);
})
.catch(error => {
console.error(error);
2020-04-25 20:01:16 +00:00
setSubmitting(false);
addError({ message: httpErrorToHuman(error) });
});
2020-04-25 20:01:16 +00:00
},
2019-06-17 01:07:57 +00:00
2020-04-25 20:01:16 +00:00
mapPropsToValues: () => ({
code: '',
recoveryCode: '',
2020-04-25 20:01:16 +00:00
}),
})(LoginCheckpointContainer);
export default ({ history, location, ...props }: OwnProps) => {
const { addError, clearFlashes } = useFlash();
if (!location.state?.token) {
history.replace('/auth/login');
return null;
}
return <EnhancedForm
addError={addError}
clearFlashes={clearFlashes}
history={history}
location={location}
{...props}
/>;
2019-06-17 01:07:57 +00:00
};