keycloak-demo-frontend/src/components/Pages/OAuth/index.tsx

81 lines
2.4 KiB
TypeScript

import React, { memo } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { Base64 } from 'js-base64';
import qs from 'qs';
import classNames from 'classnames';
import useLang from '@Hooks/useLang';
import useMessage from '@Hooks/useMessage';
import usaDidMount from '@Hooks/useDidMount';
import useReduxApi from '@Hooks/useReduxApi';
import Loading from '@Components/Base/Loading';
import { UserOAuthResponse, OAuthResult, APIError } from './types';
import Styles from './index.module.css';
function OAuth(): React.ReactElement {
/* Global & Local State */
const { i18n } = useLang();
const reduxMessage = useMessage();
const reduxUser = useReduxApi('user');
const routeHistory = useHistory();
const routeLocation = useLocation();
/* Functions */
const onOAuthSuccess = (token: string): void => {
reduxUser('postUserTokenInfoSignIn', [token]);
};
const onOAuthFailed = (error: APIError): void => {
reduxMessage.error(error);
routeHistory.push('/');
};
const parseQuery = (base64String: string): OAuthResult => {
const result = Base64.decode(base64String);
const json: OAuthResult = JSON.parse(result);
return json;
};
const validateByType = (query: UserOAuthResponse): void => {
if (Object.keys(query).length > 0) {
if (query.error) {
const parseResult = parseQuery(query.error);
const error: APIError = {
code: parseResult.code,
message: parseResult.message,
errorStack: parseResult.errorStack,
errorMessage: parseResult.errorMessage,
};
onOAuthFailed(error);
return;
}
if (query.success) {
const parseResult = parseQuery(query.success);
onOAuthSuccess(parseResult.token);
}
}
};
const initialize = async (): Promise<void> => {
const resultQuery: UserOAuthResponse = qs.parse(routeLocation.search, {
ignoreQueryPrefix: true,
});
if (Object.keys(resultQuery).length > 0) {
validateByType(resultQuery);
} else {
routeHistory.push('/');
}
};
/* Hooks */
usaDidMount(() => {
initialize();
});
/* Main */
return (
<div className={classNames(Styles.oAuthContainer)}>
<Loading
typeIcon="basic"
typePosition="absolute"
typeBackground="white"
isLoading
text={i18n.t('frontend.global.property.validate')}
/>
</div>
);
}
export default memo(OAuth);