| "i18next": "^20.3.1", | "i18next": "^20.3.1", | ||||
| "json-server": "^0.17.0", | "json-server": "^0.17.0", | ||||
| "jsonwebtoken": "^8.5.1", | "jsonwebtoken": "^8.5.1", | ||||
| "jwt-decode": "^3.1.2", | |||||
| "lodash": "^4.17.21", | "lodash": "^4.17.21", | ||||
| "lodash.isempty": "^4.4.0", | "lodash.isempty": "^4.4.0", | ||||
| "owasp-password-strength-test": "^1.3.0", | "owasp-password-strength-test": "^1.3.0", | ||||
| "safe-buffer": "^5.0.1" | "safe-buffer": "^5.0.1" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/jwt-decode": { | |||||
| "version": "3.1.2", | |||||
| "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", | |||||
| "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" | |||||
| }, | |||||
| "node_modules/keyv": { | "node_modules/keyv": { | ||||
| "version": "3.1.0", | "version": "3.1.0", | ||||
| "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", | "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", | ||||
| "safe-buffer": "^5.0.1" | "safe-buffer": "^5.0.1" | ||||
| } | } | ||||
| }, | }, | ||||
| "jwt-decode": { | |||||
| "version": "3.1.2", | |||||
| "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", | |||||
| "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" | |||||
| }, | |||||
| "keyv": { | "keyv": { | ||||
| "version": "3.1.0", | "version": "3.1.0", | ||||
| "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", | "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", |
| "i18next": "^20.3.1", | "i18next": "^20.3.1", | ||||
| "json-server": "^0.17.0", | "json-server": "^0.17.0", | ||||
| "jsonwebtoken": "^8.5.1", | "jsonwebtoken": "^8.5.1", | ||||
| "jwt-decode": "^3.1.2", | |||||
| "lodash": "^4.17.21", | "lodash": "^4.17.21", | ||||
| "lodash.isempty": "^4.4.0", | "lodash.isempty": "^4.4.0", | ||||
| "owasp-password-strength-test": "^1.3.0", | "owasp-password-strength-test": "^1.3.0", |
| Learn how to configure a non-root public URL by running `npm run build`. | Learn how to configure a non-root public URL by running `npm run build`. | ||||
| --> | --> | ||||
| <title>React App</title> | <title>React App</title> | ||||
| <script src="https://accounts.google.com/gsi/client" async defer></script> | |||||
| </head> | </head> | ||||
| <body> | <body> | ||||
| <noscript>You need to enable JavaScript to run this app.</noscript> | <noscript>You need to enable JavaScript to run this app.</noscript> |
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import HrLogo from "../../assets/images/hrcenter.png"; | import HrLogo from "../../assets/images/hrcenter.png"; | ||||
| import DiligLogo from "../../assets/images/logo_horizontal_black.png"; | import DiligLogo from "../../assets/images/logo_horizontal_black.png"; | ||||
| import jwt_decode from 'jwt-decode'; | |||||
| import googleLogo from "../../assets/images/google1.png"; | import googleLogo from "../../assets/images/google1.png"; | ||||
| import { | import { | ||||
| clearLoginErrors, | clearLoginErrors, | ||||
| fetchUser, | fetchUser, | ||||
| fetchGoogleUser | |||||
| } from "../../store/actions/login/loginActions"; | } from "../../store/actions/login/loginActions"; | ||||
| import { selectLoginError } from "../../store/selectors/loginSelectors"; | import { selectLoginError } from "../../store/selectors/loginSelectors"; | ||||
| import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../constants/pages"; | import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../constants/pages"; | ||||
| // redirectClient(); | // redirectClient(); | ||||
| // }, [history]); | // }, [history]); | ||||
| const handleCallbackResponse = (response) => { | |||||
| console.log(response.credential); | |||||
| const userObject = jwt_decode(response.credential); | |||||
| console.log(userObject); | |||||
| const username = userObject.email; | |||||
| dispatch(clearLoginErrors()); | |||||
| dispatch( | |||||
| fetchGoogleUser({ | |||||
| username, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ); | |||||
| } | |||||
| const isLoading = useSelector( | const isLoading = useSelector( | ||||
| selectIsLoadingByActionType(LOGIN_USER_LOADING) | selectIsLoadingByActionType(LOGIN_USER_LOADING) | ||||
| ); | ); | ||||
| ); | ); | ||||
| }; | }; | ||||
| const handleGoogleSubmit = (values) => { | |||||
| /* global google */ | |||||
| google.accounts.id.initialize({ | |||||
| client_id: "734219382849-nvnulsu7ibfl4bk3n164bgb7c1h5dgca.apps.googleusercontent.com", | |||||
| callback: handleCallbackResponse | |||||
| }); | |||||
| google.accounts.id.renderButton( | |||||
| document.getElementById("signInDiv"), | |||||
| { theme: "outline", size: "large"} | |||||
| ); | |||||
| }; | |||||
| const formik = useFormik({ | const formik = useFormik({ | ||||
| initialValues: { | initialValues: { | ||||
| username: "", | username: "", | ||||
| <Button | <Button | ||||
| className="c-btn c-btn--gray flex-center" | className="c-btn c-btn--gray flex-center" | ||||
| sx={{ width: "100%", mt: 2 }} | sx={{ width: "100%", mt: 2 }} | ||||
| onClick={handleGoogleSubmit} | |||||
| > | > | ||||
| <img src={googleLogo} style={{ marginRight: "15px" }} /> | <img src={googleLogo} style={{ marginRight: "15px" }} /> | ||||
| <Typography sx={{ m: 0, p: 0 }} variant="buttonText"> | <Typography sx={{ m: 0, p: 0 }} variant="buttonText"> | ||||
| </div> | </div> | ||||
| </Box> | </Box> | ||||
| </Box> | </Box> | ||||
| <div id='signInDiv'></div> | |||||
| </Container> | </Container> | ||||
| ); | ); | ||||
| }; | }; |
| const base = "http://localhost:26081/v1"; | |||||
| export default { | export default { | ||||
| authentications: { | authentications: { | ||||
| login: 'http://localhost:26081/v1/users/authenticate', | |||||
| login: base + '/users/authenticate', | |||||
| googleLogin: base + '/users/authenticateGoogle', | |||||
| }, | }, | ||||
| }; | }; |
| export const attemptLogin = (payload) => | export const attemptLogin = (payload) => | ||||
| postRequest(apiEndpoints.authentications.login, payload); | postRequest(apiEndpoints.authentications.login, payload); | ||||
| export const attemptGoogleLogin = (payload) => | |||||
| postRequest(apiEndpoints.authentications.googleLogin, payload); | |||||
| export const updateSecurityAnswer = (payload) => | export const updateSecurityAnswer = (payload) => | ||||
| postRequest(apiEndpoints.authentications.confirmSecurityQuestion, payload); | postRequest(apiEndpoints.authentications.confirmSecurityQuestion, payload); | ||||
| ); | ); | ||||
| export const LOGIN_USER_LOADING = createLoadingType(LOGIN_USER_SCOPE); | export const LOGIN_USER_LOADING = createLoadingType(LOGIN_USER_SCOPE); | ||||
| const LOGIN_GOOGLE_USER_SCOPE = 'LOGIN_GOOGLE_USER'; | |||||
| export const LOGIN_GOOGLE_USER_FETCH = createFetchType(LOGIN_GOOGLE_USER_SCOPE); | |||||
| export const LOGIN_GOOGLE_USER_SUCCESS = createSuccessType(LOGIN_GOOGLE_USER_SCOPE); | |||||
| export const LOGIN_GOOGLE_USER_ERROR = createErrorType(LOGIN_GOOGLE_USER_SCOPE); | |||||
| export const CLEAR_LOGIN_GOOGLE_USER_ERROR = createClearType( | |||||
| `${LOGIN_GOOGLE_USER_SCOPE}_ERROR`, | |||||
| ); | |||||
| export const LOGIN_GOOGLE_USER_LOADING = createLoadingType(LOGIN_USER_SCOPE); | |||||
| export const UPDATE_USER_JWT_TOKEN = 'UPDATE_USER_JWT_TOKEN'; | export const UPDATE_USER_JWT_TOKEN = 'UPDATE_USER_JWT_TOKEN'; | ||||
| export const RESET_LOGIN_STATE = 'RESET_LOGIN_STATE'; | export const RESET_LOGIN_STATE = 'RESET_LOGIN_STATE'; |
| LOGIN_USER_ERROR, | LOGIN_USER_ERROR, | ||||
| LOGIN_USER_FETCH, | LOGIN_USER_FETCH, | ||||
| LOGIN_USER_SUCCESS, | LOGIN_USER_SUCCESS, | ||||
| LOGIN_GOOGLE_USER_ERROR, | |||||
| LOGIN_GOOGLE_USER_FETCH, | |||||
| LOGIN_GOOGLE_USER_SUCCESS, | |||||
| LOGOUT_USER, | LOGOUT_USER, | ||||
| RESET_LOGIN_STATE, | RESET_LOGIN_STATE, | ||||
| UPDATE_USER_JWT_TOKEN, | UPDATE_USER_JWT_TOKEN, | ||||
| payload, | payload, | ||||
| }); | }); | ||||
| export const fetchGoogleUser = (payload) => ({ | |||||
| type: LOGIN_GOOGLE_USER_FETCH, | |||||
| payload, | |||||
| }); | |||||
| export const fetchUserSuccess = (payload) => ({ | export const fetchUserSuccess = (payload) => ({ | ||||
| type: LOGIN_USER_SUCCESS, | type: LOGIN_USER_SUCCESS, | ||||
| payload, | payload, | ||||
| }); | }); | ||||
| export const fetchGoogleUserSuccess = (payload) => ({ | |||||
| type: LOGIN_GOOGLE_USER_SUCCESS, | |||||
| payload, | |||||
| }); | |||||
| export const fetchUserError = (payload) => ({ | export const fetchUserError = (payload) => ({ | ||||
| type: LOGIN_USER_ERROR, | type: LOGIN_USER_ERROR, | ||||
| payload, | payload, | ||||
| }); | }); | ||||
| export const fetchGoogleUserError = (payload) => ({ | |||||
| type: LOGIN_GOOGLE_USER_ERROR, | |||||
| payload, | |||||
| }); | |||||
| export const updateUserToken = (payload) => ({ | export const updateUserToken = (payload) => ({ | ||||
| type: UPDATE_USER_JWT_TOKEN, | type: UPDATE_USER_JWT_TOKEN, | ||||
| payload, | payload, |
| import history from '../utils/history'; | import history from '../utils/history'; | ||||
| import { | import { | ||||
| AUTHENTICATE_USER, | AUTHENTICATE_USER, | ||||
| LOGIN_GOOGLE_USER_FETCH, | |||||
| LOGIN_USER_FETCH, | LOGIN_USER_FETCH, | ||||
| LOGOUT_USER, | LOGOUT_USER, | ||||
| REFRESH_TOKEN, | REFRESH_TOKEN, | ||||
| GENERATE_TOKEN, | GENERATE_TOKEN, | ||||
| } from '../actions/login/loginActionConstants'; | } from '../actions/login/loginActionConstants'; | ||||
| import { | import { | ||||
| attemptGoogleLogin, | |||||
| attemptLogin, | attemptLogin, | ||||
| logoutUserRequest, | logoutUserRequest, | ||||
| refreshTokenRequest, | refreshTokenRequest, | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| function* fetchGoogleUser({ payload }) { | |||||
| try { | |||||
| const { data } = yield call(attemptGoogleLogin, payload); | |||||
| if (data.token) { | |||||
| const user = jwt.decode(data.token); | |||||
| yield call(authScopeSetHelper, JWT_TOKEN, data.token); | |||||
| yield call(authScopeSetHelper, JWT_REFRESH_TOKEN, data.JwtRefreshToken); | |||||
| yield call(authScopeSetHelper, REFRESH_TOKEN_CONST, data.RefreshToken); | |||||
| yield call(addHeaderToken, data.token); | |||||
| yield put(setUser(user)); | |||||
| } | |||||
| yield put(fetchUserSuccess(data)); | |||||
| if (payload.handleApiResponseSuccess) { | |||||
| yield call(payload.handleApiResponseSuccess); | |||||
| } | |||||
| } catch (e) { | |||||
| if (e.response && e.response.data) { | |||||
| if (payload.handleApiResponseFailed) { | |||||
| yield call(payload.handleApiResponseFailed); | |||||
| } | |||||
| const errorMessage = yield call(rejectErrorCodeHelper, e); | |||||
| yield put(fetchUserError(errorMessage)); | |||||
| } | |||||
| } | |||||
| } | |||||
| function* authenticateUser() { | function* authenticateUser() { | ||||
| try { | try { | ||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | ||||
| export default function* loginSaga() { | export default function* loginSaga() { | ||||
| yield all([ | yield all([ | ||||
| takeLatest(LOGIN_USER_FETCH, fetchUser), | takeLatest(LOGIN_USER_FETCH, fetchUser), | ||||
| takeLatest(LOGIN_GOOGLE_USER_FETCH, fetchGoogleUser), | |||||
| takeLatest(AUTHENTICATE_USER, authenticateUser), | takeLatest(AUTHENTICATE_USER, authenticateUser), | ||||
| takeLatest(LOGOUT_USER, logoutUser), | takeLatest(LOGOUT_USER, logoutUser), | ||||
| takeLatest(REFRESH_TOKEN, refreshToken), | takeLatest(REFRESH_TOKEN, refreshToken), |
| "jwa" "^1.4.1" | "jwa" "^1.4.1" | ||||
| "safe-buffer" "^5.0.1" | "safe-buffer" "^5.0.1" | ||||
| "jwt-decode@^3.1.2": | |||||
| "integrity" "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" | |||||
| "resolved" "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz" | |||||
| "version" "3.1.2" | |||||
| "keyv@^3.0.0": | "keyv@^3.0.0": | ||||
| "integrity" "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==" | "integrity" "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==" | ||||
| "resolved" "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" | "resolved" "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" |