Skip to content

Commit

Permalink
Made signOut/signIn calls consistent, added spinner and cleaned up
Browse files Browse the repository at this point in the history
signIn button errors REBASE
  • Loading branch information
sjkobori committed Jun 27, 2024
1 parent 94f8bfb commit c3cb893
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 84 deletions.
3 changes: 3 additions & 0 deletions cypress/component/TermsOfService/tos_acceptance.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import React from 'react';
import { mount } from 'cypress/react';
import TermsOfServiceAcceptance from '../../../src/pages/TermsOfServiceAcceptance';
import { OidcBroker } from '../../../src/libs/auth/oidcBroker';
import { ToS } from '../../../src/libs/ajax/ToS';
import {Storage} from '../../../src/libs/storage';
import {Navigation} from '../../../src/libs/utils';
Expand All @@ -17,6 +18,8 @@ describe('Terms of Service Acceptance Page', function () {
cy.viewport(600, 300);
cy.stub(ToS, 'getDUOSText').returns(text);
cy.stub(ToS, 'acceptToS').returns(true);
cy.stub(OidcBroker, 'signIn').returns({});
cy.stub(OidcBroker, 'signOut');
cy.stub(Storage, 'getCurrentUser').returns({});
cy.stub(Navigation, 'back').returns(true);
const setUserIsLoggedSpy = cy.spy(Storage, 'setUserIsLogged');
Expand Down
4 changes: 2 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ function App() {
<div className="body">
<div className="wrap">
<div className="main">
<DuosHeader onSignOut={() => Auth.signOut()} onSignIn={() => Auth.signIn(true)} />
<DuosHeader />
<Spinner name="mainSpinner" group="duos" loadingImage={loadingImage} />
<Routes onSignOut={() => Auth.signOut()} onSignIn={() => Auth.signIn(true)} isLogged={isLoggedIn} env={env} />
<Routes isLogged={isLoggedIn} env={env} />
</div>
</div>
<DuosFooter />
Expand Down
14 changes: 6 additions & 8 deletions src/components/DuosHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import Tab from '@mui/material/Tab';
import Box from '@mui/material/Box';
import {checkEnv, envGroups} from '../utils/EnvironmentUtils';
import {isFunction, isNil} from 'lodash/fp';
import SignIn from './SignIn';
import SignInButton from './SignInButton';
import { Auth } from '../libs/auth/auth';

const styles = {
drawerPaper: {
Expand Down Expand Up @@ -143,7 +144,7 @@ const NavigationTabsComponent = (props) => {
orientation,
makeNotifications,
navbarDuosIcon, duosLogoImage, DuosLogo, navbarDuosText,
currentUser, signIn, signOut, isLogged,
currentUser, signOut, isLogged,
contactUsButton, showRequestModal, supportrequestModal,
tabs, initialTab, initialSubTab,
onSubtabChange
Expand Down Expand Up @@ -232,7 +233,7 @@ const NavigationTabsComponent = (props) => {
<div
style={{ display: 'flex', alignItems: 'center', flexDirection: orientation === 'vertical' ? 'column' : 'row' }}
>
<SignIn onSignIn={signIn} customStyle={{ whiteSpace: 'nowrap', }}></SignIn>
<SignInButton customStyle={{ whiteSpace: 'nowrap', }}></SignInButton>
</div>
)}
{isLogged && (
Expand Down Expand Up @@ -319,7 +320,7 @@ const navbarDuosText = {
};

const DuosHeader = (props) => {
const { location, classes, onSignIn } = props;
const { location, classes } = props;
const [state, setState] = useState({
showSupportRequestModal: false,
hover: false,
Expand Down Expand Up @@ -348,8 +349,7 @@ const DuosHeader = (props) => {
const signOut = () => {
props.history.push('/home');
toggleDrawer(false);

props.onSignOut();
Auth.signOut();
};

const supportRequestModal = () => {
Expand Down Expand Up @@ -483,7 +483,6 @@ const DuosHeader = (props) => {
navbarDuosText={navbarDuosText}
currentUser={currentUser}
isLogged={isLogged}
signIn={onSignIn}
signOut={signOut}
contactUsButton={contactUsButton}
supportrequestModal={supportModal}
Expand Down Expand Up @@ -530,7 +529,6 @@ const DuosHeader = (props) => {
navbarDuosText={navbarDuosText}
currentUser={currentUser}
isLogged={isLogged}
signIn={onSignIn}
signOut={signOut}
contactUsButton={contactUsButton}
supportrequestModal={supportModal}
Expand Down
141 changes: 77 additions & 64 deletions src/components/SignInButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DuosUser, User } from '../libs/ajax/User';
import { Metrics } from '../libs/ajax/Metrics';
import { Storage } from '../libs/storage';
import { Navigation, setUserRoleStatuses } from '../libs/utils';
import loadingIndicator from '../images/loading-indicator.svg';
import loadingImage from '../images/loading-indicator.svg';
import { Auth } from '../libs/auth/auth';
import eventList from '../libs/events';
import { StackdriverReporter } from '../libs/stackdriverReporter';
Expand All @@ -16,15 +16,11 @@ import { OidcUser } from 'src/libs/auth/oidcBroker';

interface SignInButtonProps {
customStyle: CSS.Properties | undefined;
history: History;
onSignIn: () => Promise<void>;
}

interface ErrorInfo {
title?: string;
description?: string;
show?: boolean;
msg?: string;
}

type ErrorDisplay = ErrorInfo | JSX.Element;
Expand All @@ -33,11 +29,11 @@ interface HttpError extends Error {
status?: number;
}



export const SignInButton = (props: SignInButtonProps) => {
const [errorDisplay, setErrorDisplay] = useState<ErrorDisplay | JSX.Element>({});
const { onSignIn, customStyle } = props;
const [errorInfo, setErrorInfo] = useState<ErrorInfo>({});
const [isLoading, setIsLoading] = useState<boolean>(false);
const [showError, setShowError] = useState<boolean>(false);
const { customStyle } = props;
const history = useHistory();

// Utility function called in the normal success case and in the undocumented 409 case
Expand All @@ -46,14 +42,15 @@ export const SignInButton = (props: SignInButtonProps) => {
// Check if the user has accepted ToS yet or not:
const user: DuosUser = await User.getMe();
if (!user.roles) {
await StackdriverReporter.report('roles not found for user: ' + user.email);
await StackdriverReporter.report(
'roles not found for user: ' + user.email
);
}
setUserRoleStatuses(user, Storage);
await onSignIn();
const userStatus = await ToS.getStatus();
const { tosAccepted } = userStatus;
if (!isEmpty(userStatus) && !tosAccepted) {
await Storage.setUserIsLogged(false);
Storage.setUserIsLogged(false);
if (isNil(redirectPath)) {
history.push(`/tos_acceptance`);
} else {
Expand Down Expand Up @@ -85,30 +82,36 @@ export const SignInButton = (props: SignInButtonProps) => {
return queryParams.get('redirectTo') || window.location.pathname;
};

const shouldRedirectTo = (page: string): boolean => page !== '/' && page !== '/home';
const shouldRedirectTo = (page: string): boolean =>
page !== '/' && page !== '/home';

const attemptSignInCheckToSAndRedirect = async (
redirectTo: string,
shouldRedirect: boolean,
shouldRedirect: boolean
) => {
await checkToSAndRedirect(shouldRedirect ? redirectTo : null);
Metrics.identify(Storage.getAnonymousId());
Metrics.syncProfile();
Metrics.captureEvent(eventList.userSignIn);
};

const handleRegistration = async (redirectTo: string, shouldRedirect: boolean) => {
const handleRegistration = async (
redirectTo: string,
shouldRedirect: boolean
) => {
try {
await registerAndRedirectNewUser(redirectTo, shouldRedirect);
} catch (error: unknown) {
await handleErrors(error as HttpError, redirectTo, shouldRedirect);
}
};

const registerAndRedirectNewUser = async (redirectTo: string, shouldRedirect: boolean) => {
const registerAndRedirectNewUser = async (
redirectTo: string,
shouldRedirect: boolean
) => {
const registeredUser = await User.registerUser();
setUserRoleStatuses(registeredUser, Storage)
await onSignIn();
setUserRoleStatuses(registeredUser, Storage);
Metrics.identify(Storage.getAnonymousId());
Metrics.syncProfile();
Metrics.captureEvent(eventList.userRegister);
Expand All @@ -117,25 +120,29 @@ export const SignInButton = (props: SignInButtonProps) => {
);
};

const handleErrors = async (error: HttpError, redirectTo: string, shouldRedirect: boolean) => {
const handleErrors = async (
error: HttpError,
redirectTo: string,
shouldRedirect: boolean
) => {
const status = error.status;

switch (status) {
case 400:
setErrorDisplay({
show: true,
setShowError(true);
setErrorInfo({
title: 'Error',
msg: JSON.stringify(error),
description: JSON.stringify(error),
});
break;
case 409:
handleConflictError(redirectTo, shouldRedirect);
break;
default:
setErrorDisplay({
show: true,
setShowError(true);
setErrorInfo({
title: 'Error',
msg: 'Unexpected error, please try again',
description: 'Unexpected error, please try again',
});
break;
}
Expand All @@ -149,51 +156,57 @@ export const SignInButton = (props: SignInButtonProps) => {
}
};

const onFailure = (response: any) => {
const onFailure = (error: Error) => {
Storage.clearStorage();
if (response.error === 'popup_closed_by_user') {
setErrorDisplay( <span>
Sign-in cancelled ...
<img height="20px" src={loadingIndicator} />
</span>
);
setTimeout(() => {
setErrorDisplay({});
}, 2000);
} else {
setErrorDisplay({ title: response.error, description: response.details });
setIsLoading(false);
if (!error.message.includes('Popup closed by user')) {
setShowError(true);
setErrorInfo({
title: 'Error',
description: error.message,
});
}
};

const loadingIndicator = (): JSX.Element => {
return (
<span>
<img height='20px' src={loadingImage} />
</span>
);
};

//TODO: Add spinner from signInPopup till registering/logging in resolves
const signInButton = (): JSX.Element => {
return (<button
className={'btn-secondary'}
style={customStyle}
onClick={() => {
Auth.signIn(true, onSuccess, onFailure);
}}
>
Sign In
</button>)
}

return (
<div>
{isEmpty(errorDisplay) ? (
<div>{signInButton()}</div>
) : (
<div className="dialog-alert">
<Alert
id="dialog"
type="danger"
title={(errorDisplay as ErrorInfo).title}
description={(errorDisplay as ErrorInfo).description} />
</div>
)}
</div>
);
return (
<button
className={'btn-secondary'}
style={customStyle}
onClick={async () => {
setIsLoading(true);
await Auth.signIn(true, onSuccess, onFailure);
setIsLoading(false);
}}
disabled={isLoading}
>
{isLoading ? loadingIndicator() : 'Sign In'}
</button>
);
};

const errorAlert = (errorInfo: ErrorInfo): JSX.Element => {
return (
<div className='dialog-alert'>
<Alert
id='dialog'
type='danger'
title={errorInfo.title}
description={errorInfo.description}
/>
</div>
);
};

return <div>{!showError ? signInButton() : errorAlert(errorInfo)}</div>;
};

export default SignInButton;
2 changes: 1 addition & 1 deletion src/libs/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ export const Auth = {
},

signOut: async () => {
Storage.setUserIsLogged(false);
Storage.clearStorage();
Storage.setUserIsLogged(false);
await OidcBroker.signOut();
},
};
9 changes: 0 additions & 9 deletions src/pages/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import homeHeaderBackground from '../images/home_header_background.png';
import duosLogoImg from '../images/duos_logo.svg';
import duosDiagram from '../images/DUOS_Homepage_diagram.svg';
import { Link } from 'react-router-dom';
import { Storage } from '../libs/storage';

const Home = (props) => {
const homeTitle = {
Expand Down Expand Up @@ -78,14 +77,6 @@ const Home = (props) => {
display: 'block'
};

const signInPositionStyle = {
padding: '1em 1em 0 0',
alignItems: 'center',
position: 'absolute',
top: '0',
right: '1rem',
};

return (
<div className="row">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
Expand Down

0 comments on commit c3cb893

Please sign in to comment.