fixed userData persisting problem, logout bug fixes and cookie expiration problem (#2045)

- Clearing data on logout was not happening (fixed)
- User was unable to login due to token not being set properly (fixed)
- Persistor was not storing the userData immediately (fixed)

Signed-off-by: arkajyotiMukherjee <arkajyoti.mukherjee@mayadata.io>
This commit is contained in:
Arkajyoti Mukherjee 2020-09-12 13:39:43 +05:30 committed by GitHub
parent daebbf6202
commit 4d976eb075
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 53 additions and 28 deletions

View File

@ -18,7 +18,6 @@
}
},
"rules": {
"import/no-cycle": 0,
"new-cap": 0,
"no-underscore-dangle": 0,
"react/static-property-placement": [

View File

@ -0,0 +1 @@
273b5b51-0311-4d9e-a428-e5abca4d6a51

View File

@ -23,7 +23,7 @@ import {
import { ProjectsCallBackType } from '../../models/header';
import useActions from '../../redux/actions';
import * as UserActions from '../../redux/actions/user';
import { history } from '../../redux/configureStore';
import configureStore, { history } from '../../redux/configureStore';
import { RootState } from '../../redux/reducers';
import getToken from '../../utils/getToken';
import userAvatar from '../../utils/user';
@ -67,10 +67,11 @@ const ProfileInfoDropdownItems: React.FC<ProfileInfoDropdownItemProps> = ({
const [switchableProjects, setSwitchableProjects] = useState<Project[]>([]);
const [loggedOut, doLogout] = useState(false);
const userData = useSelector((state: RootState) => state.userData);
// Use the persistor object
const { persistor } = configureStore();
const logOut = () => {
doLogout(true);
user.userLogout();
fetch(`${config.auth.url}/logout`, {
method: 'POST',
@ -86,6 +87,9 @@ const ProfileInfoDropdownItems: React.FC<ProfileInfoDropdownItemProps> = ({
.catch((err) => {
console.error(err);
});
user.userLogout();
// Clear data from persistor
persistor.purge();
};
const CallbackFromProjectListItem = (selectedProjectIDFromList: string) => {

View File

@ -15,6 +15,7 @@ import {
import { Message, NotificationIds } from '../../models/header';
import useActions from '../../redux/actions';
import * as UserActions from '../../redux/actions/user';
import configureStore from '../../redux/configureStore';
import { RootState } from '../../redux/reducers';
import CustomBreadCrumbs from '../BreadCrumbs';
import NotificationsDropdown from './NotificationDropdown';
@ -30,8 +31,10 @@ interface SelectedProjectDetails {
const Header: React.FC = () => {
const classes = useStyles();
const userData = useSelector((state: RootState) => state.userData);
const user = useActions(UserActions);
// Use the persistor object
const { persistor } = configureStore();
// Query to get user details
const { data } = useQuery<CurrentUserDetails, CurrentUserDedtailsVars>(
GET_USER,
@ -61,6 +64,9 @@ const Header: React.FC = () => {
userRole: member.role,
selectedProjectName: project.name,
});
// Flush data to persistor immediately
persistor.flush();
setSelectedProjectDetails({
selectedProjectID,
selectedUserRole: member.role,

View File

@ -6,6 +6,7 @@ import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import config from '../../config';
import { CREATE_USER } from '../../graphql';
import { CreateUserData } from '../../models/graphql/user';
import { RootState } from '../../redux/reducers';
import getToken from '../../utils/getToken';
import {
@ -26,15 +27,16 @@ const CStepper: React.FC<CStepperProps> = ({ handleModal }) => {
const classes = useStyles();
const { t } = useTranslation();
const { userData } = useSelector((state: RootState) => state);
const userData = useSelector((state: RootState) => state.userData);
const [activeStep, setActiveStep] = React.useState<number>(0);
const isError = useRef(true);
const isSuccess = useRef(false);
const [info, setInfo] = React.useState({
const [info, setInfo] = React.useState<CreateUserData>({
username: userData.username,
email: '',
name: '',
projectName: '',
project_name: '',
});
const handleBack = () => {
@ -57,7 +59,7 @@ const CStepper: React.FC<CStepperProps> = ({ handleModal }) => {
window.location.reload();
};
const [CreateUser] = useMutation(CREATE_USER, {
const [CreateUser] = useMutation<CreateUserData>(CREATE_USER, {
onCompleted: () => {
rerender();
},
@ -86,7 +88,7 @@ const CStepper: React.FC<CStepperProps> = ({ handleModal }) => {
username: userData.username,
email: info.email,
name: info.name,
project_name: info.projectName,
project_name: info.project_name,
},
},
});
@ -117,8 +119,8 @@ const CStepper: React.FC<CStepperProps> = ({ handleModal }) => {
// [Button State: Disabled]
if (activeStep === 0) {
if (
info.projectName.length > 0 &&
validateStartEmptySpacing(info.projectName) === false
info.project_name.length > 0 &&
validateStartEmptySpacing(info.project_name) === false
) {
isError.current = false;
} else {
@ -242,19 +244,19 @@ const CStepper: React.FC<CStepperProps> = ({ handleModal }) => {
<div className={classes.inputArea} data-cy="InputProjectName">
<InputField
label={t('welcomeModel.case-0.label')}
value={info.projectName}
value={info.project_name}
required
helperText={
validateStartEmptySpacing(info.projectName)
validateStartEmptySpacing(info.project_name)
? 'Should not start with an empty space'
: ''
}
validationError={validateStartEmptySpacing(
info.projectName
info.project_name
)}
type="text"
handleChange={(event) => {
setData('projectName', event.target.value);
setData('project_name', event.target.value);
}}
/>
</div>

View File

@ -35,3 +35,10 @@ export interface CurrentUserDetails {
export interface CurrentUserDedtailsVars {
username: string;
}
export interface CreateUserData {
username: string;
email: string;
name: string;
project_name: string;
}

View File

@ -21,7 +21,7 @@ import useActions from '../../redux/actions';
import * as TabActions from '../../redux/actions/tabs';
import * as TemplateSelectionActions from '../../redux/actions/template';
import * as UserActions from '../../redux/actions/user';
import { history } from '../../redux/configureStore';
import configureStore, { history } from '../../redux/configureStore';
import { RootState } from '../../redux/reducers';
import useStyles from './style';
@ -63,6 +63,8 @@ const HomePage: React.FC = () => {
const { t } = useTranslation();
const user = useActions(UserActions);
const tabs = useActions(TabActions);
// Use the persistor object
const { persistor } = configureStore();
// Query to get user details
const { data, loading } = useQuery<
@ -82,7 +84,10 @@ const HomePage: React.FC = () => {
if (data?.getUser.username === userData.username) {
setIsOpen(false);
if (userData.selectedProjectID === '') {
let isOwnerOfProject = { id: '', name: '' };
let isOwnerOfProject = {
id: '',
name: '',
};
const projectList: Project[] = data?.getUser.projects;
projectList.forEach((project) => {
const memberList: Member[] = project.members;
@ -91,7 +96,10 @@ const HomePage: React.FC = () => {
member.user_name === data?.getUser.username &&
member.role === 'Owner'
) {
isOwnerOfProject = { id: project.id, name: project.name };
isOwnerOfProject = {
id: project.id,
name: project.name,
};
}
});
});
@ -100,6 +108,8 @@ const HomePage: React.FC = () => {
userRole: 'Owner',
selectedProjectName: isOwnerOfProject.name,
});
// Flush data to persistor immediately
persistor.flush();
}
}
}, [data]);

View File

@ -7,7 +7,6 @@ import {
UserData,
} from '../../models/redux/user';
import { setCookie } from '../../utils/cookies';
import { history } from '../configureStore';
import createReducer from './createReducer';
const initialState: UserData = {
@ -22,11 +21,9 @@ export const userData = createReducer<UserData>(initialState, {
try {
const jwt = action.payload as string;
const data: any = jwtDecode.decode(jwt);
const expirationTime =
new Date(data.exp * 1000).getHours() -
new Date(data.iat * 1000).getHours();
const expirationTime = (data.exp - data.iat) / 3600;
setCookie('token', jwt, expirationTime);
return {
...state,
...data,
@ -46,7 +43,6 @@ export const userData = createReducer<UserData>(initialState, {
},
[UserActions.LOGOUT_USER](state: UserData, action: UserAction) {
setCookie('token', '', 1);
history.push('/login');
return {
...initialState,
};

View File

@ -115,7 +115,7 @@ const UserManagement: React.FC = () => {
setAnchorEl(null);
};
const [currRow, setCurrRow] = React.useState<UserData>(rows[0]);
const [currRow, setCurrRow] = React.useState<UserData>();
const formatDate = (date: string) => {
const day = moment(date).format('Do MMM,YYYY LT');
@ -135,9 +135,9 @@ const UserManagement: React.FC = () => {
<div>
<EditUser
handleDiv={() => setEditDiv(false)}
email={currRow.email}
fullName={currRow.name}
userName={currRow.username}
email={currRow?.email ?? ''}
fullName={currRow?.name ?? ''}
userName={currRow?.username ?? ''}
/>
</div>
) : (