{
useEffect(() => {
setOpenDialogMutable(getAppContextValue('openVerifySecretCodeModalDialog'));
setAppContextValue('secretCodeVerified', false);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [open]);
const handleClose = () => {
@@ -54,7 +55,8 @@ const VerifySecretCodeModal = ({ classes, person }) => {
code += refDigit.current.value.toString();
}
- const data = await weConnectQueryFn('verify-email-code', { personId: person.personId, code }, METHOD.POST);
+ const id = person.personId || person.id;
+ const data = await weConnectQueryFn('verify-email-code', { personId: id, code }, METHOD.POST);
console.log(`/verify-email-code response: data: ${JSON.stringify(data)}`);
if (data.emailVerified) {
setAppContextValue('secretCodeVerified', true);
@@ -85,6 +87,7 @@ const VerifySecretCodeModal = ({ classes, person }) => {
}, 50);
}
}
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [nextFocus]);
const extractDigits = (str) => {
diff --git a/src/js/contexts/ConnectAppContext.jsx b/src/js/contexts/ConnectAppContext.jsx
index d24b74f..2d1ae9c 100644
--- a/src/js/contexts/ConnectAppContext.jsx
+++ b/src/js/contexts/ConnectAppContext.jsx
@@ -96,12 +96,15 @@ export const ConnectAppContextProvider = ({ children }) => {
authLog('useFetchData in ConnectAppContext useEffect dataAuth good:', dataAuth, isSuccessAuth, isFetchingAuth);
const { isAuthenticated } = dataAuth;
setAppContextValue('authenticatedPerson', dataAuth.person);
- setAppContextValue('isAuthenticated', isAuthenticated);
- setAppContextValue('loggedInPersonIsAdmin', dataAuth.loggedInPersonIsAdmin);
+ if (dataAuth.person) {
+ setAppContextValue('isAuthenticated', isAuthenticated);
+ setAppContextValue('loggedInPersonIsAdmin', dataAuth.loggedInPersonIsAdmin);
+ }
captureAccessRightsData(dataAuth, isSuccessAuth, apiDataCache, dispatch);
console.log('=============== ConnectAppContextProvider ======= isAuthenticated: ', isAuthenticated, ' ===========');
}
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [dataAuth, isSuccessAuth]);
return (
diff --git a/src/js/pages/Login.jsx b/src/js/pages/Login.jsx
index 3f4555e..18a705c 100644
--- a/src/js/pages/Login.jsx
+++ b/src/js/pages/Login.jsx
@@ -3,10 +3,9 @@ import { withStyles } from '@mui/styles';
import PropTypes from 'prop-types';
import React, { useEffect, useRef, useState } from 'react';
import { Helmet } from 'react-helmet-async';
-import { useNavigate } from 'react-router';
import styled from 'styled-components';
import validator from 'validator';
-import { renderLog } from '../common/utils/logging';
+import { authLog, renderLog } from '../common/utils/logging';
import compileDate from '../compileDate';
import ResetYourPassword from '../components/Login/ResetYourPassword';
import { PageContentContainer } from '../components/Style/pageLayoutStyles';
@@ -22,7 +21,6 @@ import weConnectQueryFn, { METHOD, useFetchData } from '../react-query/WeConnect
const Login = ({ classes }) => {
renderLog('Login');
- const navigate = useNavigate();
const { apiDataCache, getAppContextValue, setAppContextValue, getAppContextData } = useConnectAppContext();
const dispatch = useConnectDispatch();
const { mutate: mutateLogout } = useLogoutMutation();
@@ -43,16 +41,19 @@ const Login = ({ classes }) => {
const [showCreateStuff, setShowCreateStuff] = useState(false);
const [successLine, setSuccessLine] = useState('');
const [warningLine, setWarningLine] = useState('');
+ const [loginCount, setLoginCount] = useState(0);
const { data: dataAuth, isSuccess: isSuccessAuth, isFetching: isFetchingAuth } = useFetchData(['get-auth'], {}, METHOD.POST);
useEffect(() => {
if (isSuccessAuth) {
- console.log('useFetchData in Login useEffect dataAuth good:', dataAuth, isSuccessAuth, isFetchingAuth);
+ authLog('useFetchData get-auth in Login dataAuth:', dataAuth, isSuccessAuth, isFetchingAuth);
const { isAuthenticated, person: authenticatedPerson, emailVerified: emailVerifiedFromAPI, personId } = dataAuth;
authPerson.current = authenticatedPerson;
+ if (authenticatedPerson) {
+ setAppContextValue('isAuthenticated', isAuthenticated);
+ }
captureAccessRightsData(dataAuth, isSuccessAuth, apiDataCache, dispatch);
- console.log('appContextData in Login [dataAuth, isSuccessAuth]: ', getAppContextData());
if (!emailVerifiedFromAPI && personId > 0) {
setWarningLine('');
setSuccessLine('A verification email has been sent to your address');
@@ -61,16 +62,26 @@ const Login = ({ classes }) => {
setSuccessLine(`Signed in as ${getFullNamePreferredPerson(authenticatedPerson)}`);
setAppContextValue('loggedInPersonIsAdmin', dataAuth.loggedInPersonIsAdmin);
if (loginAttempted) { // if we navigate to here directly, not as a result of a loginAPI
- setTimeout(() => {
- navigate('/tasks');
- }, 2000);
+ // setTimeout(() => {
+ // navigate('/tasks');
+ setAppContextValue('navigatedFromLogin', true);
+ // }, 2000);
}
- } else {
+ } else if (!getAppContextValue('openVerifySecretCodeModalDialog')) {
+ // console.log('======== appContextData in Login: Please sign in');
setSuccessLine('Please sign in');
}
}
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [dataAuth, isSuccessAuth]);
+ const isAuth = getAppContextValue('isAuthenticated');
+ useEffect(() => {
+ // rerender if logged out from HeaderBar
+ setLoginCount(loginCount + 1);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [isAuth]);
+
const loginApi = async (email, password) => {
if (!validator.isEmail(email)) {
setWarningLine('Please enter a valid email address.');
@@ -85,16 +96,18 @@ const Login = ({ classes }) => {
setLoginAttempted(true); // so we know when to timeout to /tasks
const data = await weConnectQueryFn('login', { email, password }, METHOD.POST);
- console.log(`/login response -- status: '${'status'}', data: ${JSON.stringify(data)}`);
- if (data.personId > 0) {
+ // console.log(`/login response -- status: '${'status'}', data: ${JSON.stringify(data)}`);
+ // console.log('appContextData in Login after /login response: ', getAppContextData());
+ if (data?.personId > 0) {
setAppContextValue('isAuthenticated', data.emailVerified);
+ setAppContextValue('authenticatedPerson', data.person);
if (data.emailVerified) {
setWarningLine('');
+ passwordFldRef.current = ''; // Blank the email field after signing in
setSuccessLine(`${getFullNamePreferredPerson(data.person)}, you are signed in!`);
- setAppContextValue('authenticatedPerson', data);
- setTimeout(() => {
- navigate('/tasks');
- }, 2000);
+ // setTimeout(() => {
+ // navigate('/tasks');
+ // }, 4000);
} else {
authPerson.current = { // just enough data for VerifySecretCodeModal
personId: data.personId,
@@ -104,32 +117,47 @@ const Login = ({ classes }) => {
setSuccessLine('A verification email has been sent to your address');
}
} else {
- setWarningLine(data.error.msg);
+ setWarningLine(data?.error?.msg || 'error message with bad data');
setSuccessLine('');
}
};
+ const clearOnCreate = () => {
+ console.log('clearOnCreate -------------- 1 ------------ ', openResetPasswordDialog);
+ if (!openResetPasswordDialog) {
+ console.log('clearOnCreate -------------- 2 ------------ ', openResetPasswordDialog);
+ setAppContextValue('resetEmail', '');
+ setAppContextValue('resetPassword', '');
+ setAppContextValue('openVerifySecretCodeModalDialog', false);
+ setAppContextValue('secretCodeVerified', false);
+ setAppContextValue('secretCodeVerifiedForReset', false);
+ setShowCreateStuff(false);
+ const per = authPerson.current ? authPerson.current : getAppContextValue('authenticatedPerson');
+ setSuccessLine(`${getFullNamePreferredPerson(per)}, you are signed in!`);
+ passwordFldRef.current = ''; // Blank the email field after signing in
+ }
+ };
+
const secretCodeVerified = getAppContextValue('secretCodeVerified');
- const resetPassword = getAppContextValue('resetPassword');
+ const resetPassword = getAppContextValue('resetPassword') || '';
useEffect(() => {
- if (secretCodeVerified === true && resetPassword && resetPassword.length) {
+ if (secretCodeVerified === true) {
+ loginApi(emailPersonalFldRef.current.value, passwordFldRef.current.value).then(() => {
+ clearOnCreate();
+ });
+ } else if (resetPassword && resetPassword.length) {
loginApi(getAppContextValue('resetEmail'), getAppContextValue('resetPassword')).then(() => {
- // console.log('--------- useEffect secretCodeVerified in Login, clearing resetEmail and resetPassword', e, p);
- setAppContextValue('resetEmail', '');
- setAppContextValue('resetPassword', '');
- setAppContextValue('openVerifySecretCodeModalDialog', false);
- setAppContextValue('secretCodeVerified', false);
- setAppContextValue('secretCodeVerifiedForReset', false);
- // console.log('appContextData in Login L124: ', getAppContextData());
+ clearOnCreate();
});
}
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [secretCodeVerified, resetPassword]);
- const logoutApi = async () => {
- const data = await weConnectQueryFn('logout', {}, METHOD.POST);
+ const logoutApiInLogin = async () => {
+ const data = await weConnectQueryFn('logout', { credentials: 'same-origin' }, METHOD.POST);
console.log(`/logout response -- status: '${'status'}', data: ${JSON.stringify(data)}`);
if (data.authenticated) {
- setWarningLine(data.errors.msg);
+ setWarningLine(data?.errors?.msg);
setSuccessLine('');
} else {
setWarningLine('');
@@ -156,11 +184,13 @@ const Login = ({ classes }) => {
console.log(`/signup response -- status: '${'status'}', data: ${JSON.stringify(data)}`);
let errStr = '';
for (let i = 0; i < data.errors.length; i++) {
- errStr += data.errors[i].msg;
+ errStr += data.errors[i]?.msg;
}
setWarningLine(errStr);
if (data.personCreated) {
setSuccessLine(`user # ${data.personId} created`);
+ setSuccessLine(`user # ${data.personId} created`);
+ authPerson.current = data.person;
verifyYourEmail(data.personId).then(() => {
setSuccessLine('A verification email has been sent to your address');
console.log('verifyYourEmail in signupApi then clause , openVerifySecretCodeModalDialog true');
@@ -173,8 +203,8 @@ const Login = ({ classes }) => {
};
const loginPressed = () => {
- const email = emailPersonalFldRef.current.value;
- const password = passwordFldRef.current.value;
+ const email = (emailPersonalFldRef.current.value).trim();
+ const password = (passwordFldRef.current.value).trim();
if (email.length === 0 || password.length === 0) {
console.log('too short');
@@ -185,11 +215,24 @@ const Login = ({ classes }) => {
}
};
- const useSignOutPressed = () => {
- // clearSignedInGlobals is also called in logoutApi, so isn't needed here
- // TODO 2/23/25: unfortunately there are two logoutApi(), consolidating them is high priority
+ const removeSessionCookie = () => {
+ const urlObject = new URL(webAppConfig.STAFF_API_SERVER_ROOT_URL);
+ const updatedCookie = `WeConnectSession=; Max-Age=0; path=/; domain=${urlObject.hostname}`;
+ document.cookie = updatedCookie;
+ console.log('Login removeSessionCookie, cookie that was removed: ', updatedCookie);
+ };
+
+ const closeResetYourPassword = () => {
+ clearSignedInGlobals(setAppContextValue, getAppContextData);
+ console.log('closeResetYourPassword in Login before logutApiInLogin()');
+ logoutApiInLogin().then(() => removeSessionCookie());
+ };
+
+ const signOutButtonPressed = () => {
clearSignedInGlobals(setAppContextValue, getAppContextData);
- logoutApi().then();
+ setOpenResetPasswordDialog(false);
+ console.log('signOutButtonPressed in Login before logutApiInLogin()');
+ logoutApiInLogin().then(() => removeSessionCookie());
};
const createPressed = () => {
@@ -224,8 +267,19 @@ const Login = ({ classes }) => {
}
};
+ const createForSomeoneElsePressed = () => {
+ console.log('NOT YET IMPLEMENTED');
+ };
// console.log(getAppContextData());
+ const isAdmin = getAppContextValue('loggedInPersonIsAdmin') || false;
+ const isAuthSafe = getAppContextValue('isAuthenticated') || false;
+ const displayVerify =
+ authPerson.current &&
+ Object.keys(authPerson.current).length > 0 &&
+ getAppContextValue('secretCodeVerified') !== true &&
+ (getAppContextValue('openVerifySecretCodeModalDialog') || false);
+
return (
@@ -331,21 +385,33 @@ const Login = ({ classes }) => {
-
+ {!isAuthSafe && (
+
+ )}
+ {isAdmin && (
+
+ )}
- {authPerson.current &&
- Object.keys(authPerson.current).length > 0 &&
- getAppContextValue('secretCodeVerified') !== true &&
- getAppContextValue('openVerifySecretCodeModalDialog') && (
-
- )}
-
+ {displayVerify && }
+
{/* This following test can be deleted or converted to an automated test */}
{/* */}
diff --git a/src/js/pages/Teams.jsx b/src/js/pages/Teams.jsx
index 2f273dc..8b9e0c0 100644
--- a/src/js/pages/Teams.jsx
+++ b/src/js/pages/Teams.jsx
@@ -210,7 +210,7 @@ const Teams = () => {
})}
- Sign in
+ Temporary link to /login page
diff --git a/src/js/react-query/mutations.jsx b/src/js/react-query/mutations.jsx
index a8ac99b..922c08b 100644
--- a/src/js/react-query/mutations.jsx
+++ b/src/js/react-query/mutations.jsx
@@ -1,4 +1,5 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
+import { reactQueryLog } from '../common/utils/logging';
import { useConnectAppContext } from '../contexts/ConnectAppContext';
import weConnectQueryFn, { METHOD } from './WeConnectQuery';
@@ -100,16 +101,6 @@ const usePersonSaveMutation = () => {
});
};
-const usePersonSaveForAuthMutation = () => {
- const queryClient = useQueryClient();
-
- return useMutation({
- mutationFn: (params) => weConnectQueryFn('person-save', params, METHOD.GET),
- onError: (error) => console.log('error in personSaveMutation: ', error),
- onSuccess: () => queryClient.invalidateQueries('get-auth'),
- });
-};
-
const useSaveTaskMutation = () => {
const queryClient = useQueryClient();
@@ -134,33 +125,39 @@ const useGetAuthMutation = () => {
return useMutation({
mutationFn: () => weConnectQueryFn('get-auth', {}, METHOD.POST),
onError: (error) => console.log('error in useGetAuthMutation: ', error),
- onSuccess: () => console.log('useGetAuthMutation called to force refresh'),
+ onSuccess: (auth) => reactQueryLog('useGetAuthMutation called to force refresh', auth),
+ });
+};
+
+const usePasswordSaveMutation = () => {
+ return useMutation({
+ mutationFn: (params) => weConnectQueryFn('save-password', params, METHOD.PUT),
+ onError: (error) => console.log('error in usePasswordSaveMutation: ', error),
+ onSuccess: (data, variables, context) => reactQueryLog('usePasswordSaveMutation successful, returning', data, variables, context),
});
};
const usePersonRetrieveMutation = () => {
- console.log('entry to useGetPersonMutation');
const { setAppContextValue } = useConnectAppContext();
return useMutation({
mutationFn: (params) => weConnectQueryFn('person-retrieve', params, METHOD.GET),
onError: (error) => console.log('error in usePersonRetrieveMutation: ', error),
onSuccess: (data, variables, context) => {
- console.log('usePersonRetrieveMutation successful, returning', data, variables, context);
+ reactQueryLog('usePersonRetrieveMutation successful, returning', data, variables, context);
setAppContextValue('authenticatedPerson', data);
},
});
};
const usePersonRetrieveByEmailMutation = () => {
- console.log('entry to useGetPersonMutation');
const { setAppContextValue } = useConnectAppContext();
return useMutation({
mutationFn: (params) => weConnectQueryFn('person-retrieve-by-email', params, METHOD.GET),
onError: (error) => console.log('error in usePersonRetrieveByEmailMutation: ', error),
onSuccess: (data, variables, context) => {
- console.log('usePersonRetrieveByEmailMutation successful, returning', data, variables, context);
+ reactQueryLog('usePersonRetrieveByEmailMutation successful, returning', data, variables, context);
setAppContextValue('authenticatedPerson', data);
},
});
@@ -169,7 +166,7 @@ const usePersonRetrieveByEmailMutation = () => {
export { useRemoveTeamMutation, useRemoveTeamMemberMutation, useAddPersonToTeamMutation,
useQuestionnaireSaveMutation, useTaskDefinitionSaveMutation, useGroupSaveMutation,
- usePersonAwaySaveMutation,
- useQuestionSaveMutation, usePersonSaveMutation, usePersonSaveForAuthMutation, useSaveTaskMutation, useAnswerListSaveMutation,
+ usePersonAwaySaveMutation, usePasswordSaveMutation,
+ useQuestionSaveMutation, usePersonSaveMutation, useSaveTaskMutation, useAnswerListSaveMutation,
useLogoutMutation, useGetAuthMutation, usePersonRetrieveMutation, usePersonRetrieveByEmailMutation };