Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions src/containers/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ import { loggedInUserIdSelector, accessTokenSelector } from '../../redux/selecto
import { fetchUserIfNeeded } from '../../redux/modules/users.js';
import { fetchUserStatus } from '../../redux/selectors/users.js';
import { isTokenValid, isTokenInNeedOfRefreshment } from '../../redux/helpers/token';
import { addNotification } from '../../redux/modules/notifications.js';
import { logout, refresh } from '../../redux/modules/auth.js';
import { resourceStatus } from '../../redux/helpers/resourceManager';
import { suspendAbortPendingRequestsOptimization } from '../../pages/routes.js';
import { SESSION_EXPIRED_MESSAGE } from '../../redux/helpers/api/tools.js';
import withRouter, { withRouterProps } from '../../helpers/withRouter.js';

import './siscodex.css';
Expand Down Expand Up @@ -69,20 +67,18 @@ class App extends Component {
* must be checked more often.
*/
checkAuthentication = () => {
const { isLoggedIn, accessToken, refreshToken, logout, addNotification } = this.props;
const { isLoggedIn, accessToken, refreshToken, logout } = this.props;

const token = accessToken ? accessToken.toJS() : null;
if (isLoggedIn) {
if (!isTokenValid(token)) {
logout();
addNotification(SESSION_EXPIRED_MESSAGE, false);
} else if (isTokenInNeedOfRefreshment(token) && !this.isRefreshingToken) {
suspendAbortPendingRequestsOptimization();
this.isRefreshingToken = true;
refreshToken()
.catch(() => {
logout();
addNotification(SESSION_EXPIRED_MESSAGE, false);
})
.then(() => {
this.isRefreshingToken = false;
Expand All @@ -104,7 +100,6 @@ App.propTypes = {
loadAsync: PropTypes.func.isRequired,
refreshToken: PropTypes.func.isRequired,
logout: PropTypes.func.isRequired,
addNotification: PropTypes.func.isRequired,
location: withRouterProps.location,
};

Expand All @@ -123,7 +118,6 @@ export default withRouter(
loadAsync: userId => App.loadAsync({}, dispatch, { userId }),
refreshToken: () => dispatch(refresh()),
logout: () => dispatch(logout()),
addNotification: (msg, successful) => dispatch(addNotification(msg, successful)),
})
)(App)
);
2 changes: 2 additions & 0 deletions src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@
"app.homepage.termsPage": "Správa semestrů a jejich souvisejících dat (kdy jsou aktivní pro studenty a učitele).",
"app.homepage.title": "Rozšíření SIS-CodEx",
"app.homepage.userPage": "Stránka s osobními údaji umožnujě synchronizovat uživatelský profil (jméno, tituly, email) s daty ze SISu.",
"app.homepage.userSessionExpired": "Vaše uživatelská relace vypršela",
"app.homepage.userSessionExpiredInfo": "Musíte inicializovat novou relaci opětovným vstupem do této aplikace z ReCodExu.",
"app.localizedTexts.validation.noLocalizedText": "Prosíme povolte alespoň jednu záložku s lokalizovanými texty.",
"app.notifications.hideAll": "Pouze nové notifikace",
"app.notifications.showAll": "Zobrazit {count, plural, one {jednu starou notifikaci} two {dvě staré notifikace} other {# starých notifikací}}",
Expand Down
4 changes: 3 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@
"app.homepage.termsPage": "Management of terms and their related dates (when they are active for students and teachers).",
"app.homepage.title": "SiS-CodEx Extension",
"app.homepage.userPage": "The personal data integration page allows updating ReCodEx user profile (name, titles, email) using data from SIS.",
"app.homepage.userSessionExpired": "Your user session has expired",
"app.homepage.userSessionExpiredInfo": "You need to initialize a new session by re-entering this application from ReCodEx.",
"app.localizedTexts.validation.noLocalizedText": "Please enable at least one tab of localized texts.",
"app.notifications.hideAll": "Only new notifications",
"app.notifications.showAll": "Show {count, plural, one {old notification} two {two old notifications} other {all # notifications}}",
Expand Down Expand Up @@ -265,4 +267,4 @@
"generic.operationFailed": "The operation has failed",
"generic.reset": "Reset",
"generic.save": "Save"
}
}
28 changes: 28 additions & 0 deletions src/pages/Home/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Row, Col } from 'react-bootstrap';
import { Link } from 'react-router-dom';

import Page from '../../components/layout/Page';
import PageContent from '../../components/layout/PageContent';
import Icon, {
GroupFocusIcon,
HomeIcon,
Expand Down Expand Up @@ -88,6 +89,33 @@ class Home extends Component {
links: { USER_URI, TERMS_URI, GROUPS_STUDENT_URI, GROUPS_TEACHER_URI, GROUPS_SUPERADMIN_URI },
} = this.props;

if (!loggedInUser && !token) {
return (
<PageContent
icon={<HomeIcon />}
title={<FormattedMessage id="app.homepage.title" defaultMessage="SiS-CodEx Extension" />}
windowTitle={<FormattedMessage id="app.homepage.title" defaultMessage="SiS-CodEx Extension" />}>
<Callout variant="warning" className="my-3">
<h4>
<FormattedMessage id="app.homepage.userSessionExpired" defaultMessage="Your user session has expired" />
</h4>
<p>
<FormattedMessage
id="app.homepage.userSessionExpiredInfo"
defaultMessage="You need to initialize a new session by re-entering this application from ReCodEx."
/>
</p>
<p>
<a href={getReturnUrl()}>
<ReturnIcon gapRight />
<FormattedMessage id="app.homepage.returnToReCodEx" defaultMessage="Return to ReCodEx..." />
</a>
</p>
</Callout>
</PageContent>
);
}

return (
<Page
resource={loggedInUser}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Home from './Home';
import Terms from './Terms';
import User from './User';

import { createLoginLinkWithRedirect, abortAllPendingRequests } from '../redux/helpers/api/tools.js';
import { abortAllPendingRequests } from '../redux/helpers/api/tools.js';
import { API_BASE, URL_PATH_PREFIX } from '../helpers/config.js';
import withRouter from '../helpers/withRouter.js';

Expand Down Expand Up @@ -83,7 +83,7 @@ const routesDescriptors = [

const getRedirect = (routeObj, urlPath, isLoggedIn) => {
if (routeObj.auth !== undefined && routeObj.auth !== isLoggedIn) {
return routeObj.auth ? createLoginLinkWithRedirect(urlPath) : getLinks().DASHBOARD_URI;
return getLinks().HOME_URI;
} else {
return null;
}
Expand Down
15 changes: 2 additions & 13 deletions src/redux/helpers/api/tools.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import statusCode from 'statuscode';
import { flatten } from 'flat';
import { Buffer } from 'buffer';

import { addNotification } from '../../modules/notifications.js';
import { newPendingFetchOperation, completedFetchOperation } from '../../modules/app.js';
import { isTokenValid, decode } from '../../helpers/token';
import { API_BASE, URL_PATH_PREFIX } from '../../../helpers/config.js';
import { API_BASE } from '../../../helpers/config.js';
import { actionTypes as authActionTypes } from '../../modules/authTypes.js';
import { canUseDOM } from '../../../helpers/common.js';

Expand Down Expand Up @@ -134,15 +133,6 @@ export const logout = () => ({
type: authActionTypes.LOGOUT,
});

export const SESSION_EXPIRED_MESSAGE =
'Your session expired and you were automatically logged out of the ReCodEx system.';
export const LOGIN_URI_PREFIX = 'login';

export const createLoginLinkWithRedirect = redirLocation => {
const redirBase64 = Buffer.from(redirLocation).toString('base64');
return `${URL_PATH_PREFIX}/${LOGIN_URI_PREFIX}/${encodeURIComponent(redirBase64)}`;
};

/**
* Create a request and setup the processing of the response.
* @param {Object} request The request settings and data
Expand Down Expand Up @@ -170,7 +160,6 @@ export const createApiCallPromise = (
if (res.status === 401 && !isTokenValid(decode(accessToken)) && dispatch) {
abortAllPendingRequests();
dispatch(logout());
dispatch(addNotification(SESSION_EXPIRED_MESSAGE, false));
return Promise.reject(res);
}

Expand All @@ -184,7 +173,7 @@ export const createApiCallPromise = (
};

/**
* A specific error means that there is a problem with the Internet connectin or the server is down.
* A specific error means that there is a problem with the Internet connecting or the server is down.
* @param {Object} err The error description
* @param {Function} dispatch
*/
Expand Down