Przeglądaj źródła

Merge branch 'feature/google_login' of Neca/HRCenter into FE_dev

feature/1376_logout_possibility_fe
safet.purkovic 3 lat temu
rodzic
commit
f8cfffcb18

+ 11
- 0
package-lock.json Wyświetl plik

"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",

+ 1
- 0
package.json Wyświetl plik

"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",

+ 1
- 0
public/index.html Wyświetl plik

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>

+ 14
- 0
src/assets/styles/_base.scss Wyświetl plik

ul { ul {
list-style: none; list-style: none;
padding: 0; padding: 0;
}

.S9gUrf-YoZ4jf {
@include flex-center;
width: 100% !important;
overflow: hidden;
padding: 0 !important;
margin: 0 !important;
}

.S9gUrf-YoZ4jf > * {
margin: auto;
padding: 0 !important;
margin: 0 !important;
} }

+ 63
- 10
src/pages/LoginPage/LoginPageMUI.js Wyświetl plik

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";
const error = useSelector(selectLoginError); const error = useSelector(selectLoginError);


const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
const [isInit, setIsInit] = useState(true);
const handleClickShowPassword = () => setShowPassword(!showPassword); const handleClickShowPassword = () => setShowPassword(!showPassword);
const handleMouseDownPassword = () => setShowPassword(!showPassword); const handleMouseDownPassword = () => setShowPassword(!showPassword);


redirectClient(); redirectClient();
}, [history]); }, [history]);


const handleCallbackResponse = (response) => {
const userObject = jwt_decode(response.credential);
const user = userObject;
const token = response.credential;
dispatch(clearLoginErrors());
dispatch(
fetchGoogleUser({
user,
token,
handleApiResponseSuccess,
})
);
};

const isLoading = useSelector( const isLoading = useSelector(
selectIsLoadingByActionType(LOGIN_USER_LOADING) selectIsLoadingByActionType(LOGIN_USER_LOADING)
); );
}; };


const handleSubmit = (values) => { const handleSubmit = (values) => {
const { username,password } = values;
const { username, password } = values;
dispatch(clearLoginErrors()); dispatch(clearLoginErrors());
dispatch( dispatch(
fetchUser({ fetchUser({
); );
}; };


useEffect(() => {
if (isInit) {
setIsInit(false);
return;
}

google.accounts.id.initialize({
client_id:
"734219382849-nvnulsu7ibfl4bk3n164bgb7c1h5dgca.apps.googleusercontent.com",
callback: handleCallbackResponse,
});
google.accounts.id.renderButton(document.getElementById("signInDiv"), {
theme: "outline",
size: "large",
width: "250",
});
}, [isInit]);

// 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: "",
<div className="hr-mid">{t("common.or")}</div> <div className="hr-mid">{t("common.or")}</div>
<div className="hr hr-e"></div> <div className="hr hr-e"></div>
</div> </div>
<Button
className="c-btn c-btn--gray flex-center"
sx={{ width: "100%", mt: 2 }}
>
<img src={googleLogo} style={{ marginRight: "15px" }} />
<Typography sx={{ m: 0, p: 0 }} variant="buttonText">
{t("login.signInWithGoogle")}
</Typography>
</Button>
<div>
{/* <Button
className="c-btn c-btn--gray flex-center"
sx={{ width: "100%", mt: 2 }}
onClick={handleGoogleSubmit}
>
<img src={googleLogo} style={{ marginRight: "15px" }} />
<Typography sx={{ m: 0, p: 0 }} variant="buttonText">
{t("login.signInWithGoogle")}
</Typography>
</Button> */}
<div id="signInDiv"></div>
</div>
<div className="flex-center"> <div className="flex-center">
<img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} /> <img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} />
</div> </div>

+ 5
- 2
src/request/apiEndpoints.js Wyświetl plik

const base = "http://localhost:26081/v1";

export default { export default {
authentications: { authentications: {
login: 'http://localhost:26081/v1/users/authenticate',
refreshToken:'http://localhost:26081/v1/users/refresh'
login: base + "/users/authenticate",
googleLogin: base + "/users/authenticateGoogle",
refreshToken: base + "/users/refresh",
}, },
}; };

+ 3
- 0
src/request/loginRequest.js Wyświetl plik

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);



+ 9
- 0
src/store/actions/login/loginActionConstants.js Wyświetl plik

); );
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';

+ 18
- 0
src/store/actions/login/loginActions.js Wyświetl plik

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

+ 28
- 0
src/store/saga/loginSaga.js Wyświetl plik

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(data));
}
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),

+ 5
- 0
yarn.lock Wyświetl plik

"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"

Ładowanie…
Anuluj
Zapisz