Merge pull request #145 from ONLYOFFICE/bugfix/login-fix

Bugfix/login fix
This commit is contained in:
Alexey Safronov 2020-12-07 13:42:42 +03:00 committed by GitHub
commit dbc30ff4ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 430 additions and 307 deletions

View File

@ -239,16 +239,5 @@
To begin the development, run `npm start` or `yarn start`. To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<script>
if (localStorage.getItem("asc_auth_key")){
let el = document.getElementById("burger-loader-svg");
let el1 = document.getElementById("logo-loader-svg");
let el2 = document.getElementById("avatar-loader-svg");
el.style.display = "block";
el1.style.display = "block";
el2.style.display = "block";
}
</script>
</body> </body>
</html> </html>

View File

@ -10,7 +10,6 @@ import config from "../package.json";
import { import {
store as commonStore, store as commonStore,
constants,
history, history,
PrivateRoute, PrivateRoute,
PublicRoute, PublicRoute,
@ -32,8 +31,8 @@ const {
setCurrentProductId, setCurrentProductId,
setCurrentProductHomePage, setCurrentProductHomePage,
getPortalCultures, getPortalCultures,
getIsAuthenticated,
} = commonStore.auth.actions; } = commonStore.auth.actions;
const { AUTH_KEY } = constants;
class App extends React.Component { class App extends React.Component {
constructor(props) { constructor(props) {
@ -43,8 +42,6 @@ class App extends React.Component {
} }
componentDidMount() { componentDidMount() {
utils.removeTempContent();
const { const {
setModuleInfo, setModuleInfo,
getUser, getUser,
@ -53,14 +50,16 @@ class App extends React.Component {
getPortalCultures, getPortalCultures,
fetchTreeFolders, fetchTreeFolders,
setIsLoaded, setIsLoaded,
getIsAuthenticated,
} = this.props; } = this.props;
setModuleInfo(); setModuleInfo();
getIsAuthenticated().then((isAuthenticated) => {
const token = localStorage.getItem(AUTH_KEY); if (!isAuthenticated) {
utils.updateTempContent();
if (!token) {
return setIsLoaded(); return setIsLoaded();
} else {
utils.updateTempContent(isAuthenticated);
} }
const requests = this.isEditor const requests = this.isEditor
@ -78,8 +77,10 @@ class App extends React.Component {
toastr.error(e); toastr.error(e);
}) })
.finally(() => { .finally(() => {
utils.updateTempContent();
setIsLoaded(); setIsLoaded();
}); });
});
} }
render() { render() {
@ -140,6 +141,7 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => { const mapDispatchToProps = (dispatch) => {
return { return {
getIsAuthenticated: () => getIsAuthenticated(dispatch),
setModuleInfo: () => { setModuleInfo: () => {
dispatch(setCurrentProductHomePage(config.homepage)); dispatch(setCurrentProductHomePage(config.homepage));
dispatch(setCurrentProductId("e67be73d-f9ae-4ce1-8fec-1880cb518cb4")); dispatch(setCurrentProductId("e67be73d-f9ae-4ce1-8fec-1880cb518cb4"));

View File

@ -107,7 +107,7 @@ class ArticleBodyContent extends React.Component {
const { showNewFilesPanel, expandedKeys, newFolderId } = this.state; const { showNewFilesPanel, expandedKeys, newFolderId } = this.state;
//console.log("Article Body render", this.props, this.state.expandedKeys); //console.log("Article Body render", this.props, this.state.expandedKeys);
console.log("Article Body render"); //console.log("Article Body render");
return ( return (
<> <>
{showNewFilesPanel && ( {showNewFilesPanel && (

View File

@ -1496,7 +1496,7 @@ class SectionBodyContent extends React.Component {
}; };
render() { render() {
console.log("Files Home SectionBodyContent render", this.props); //console.log("Files Home SectionBodyContent render", this.props);
const { const {
viewer, viewer,

View File

@ -295,7 +295,7 @@ class SectionFilterContent extends React.Component {
} }
render() { render() {
console.log("Filter render"); //console.log("Filter render");
const selectedFilterData = this.getSelectedFilterData(); const selectedFilterData = this.getSelectedFilterData();
const { t, language, firstLoad, sectionWidth } = this.props; const { t, language, firstLoad, sectionWidth } = this.props;
const filterColumnCount = const filterColumnCount =

View File

@ -128,7 +128,7 @@ class PureHome extends React.Component {
if (filter) { if (filter) {
const folderId = filter.folder; const folderId = filter.folder;
console.log("filter", filter); //console.log("filter", filter);
return fetchFiles(folderId, filter); return fetchFiles(folderId, filter);
} }
@ -165,7 +165,7 @@ class PureHome extends React.Component {
} }
render() { render() {
console.log("Home render"); //console.log("Home render");
const { const {
progressData, progressData,
viewAs, viewAs,

View File

@ -9,10 +9,7 @@ import "./custom.scss";
import App from "./App"; import App from "./App";
import * as serviceWorker from "./serviceWorker"; import * as serviceWorker from "./serviceWorker";
import { ErrorBoundary, utils } from "asc-web-common"; import { ErrorBoundary } from "asc-web-common";
const { redirectToDefaultPage } = utils;
redirectToDefaultPage();
ReactDOM.render( ReactDOM.render(
<Provider store={store}> <Provider store={store}>

View File

@ -239,16 +239,5 @@
To begin the development, run `npm start` or `yarn start`. To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<script>
if (localStorage.getItem("asc_auth_key")){
let el = document.getElementById("burger-loader-svg");
let el1 = document.getElementById("logo-loader-svg");
let el2 = document.getElementById("avatar-loader-svg");
el.style.display = "block";
el1.style.display = "block";
el2.style.display = "block";
}
</script>
</body> </body>
</html> </html>

View File

@ -16,7 +16,6 @@ import {
Offline, Offline,
utils, utils,
store as commonStore, store as commonStore,
constants,
NavMenu, NavMenu,
Main, Main,
toastr, toastr,
@ -34,8 +33,8 @@ const {
setCurrentProductHomePage, setCurrentProductHomePage,
getPortalPasswordSettings, getPortalPasswordSettings,
getPortalCultures, getPortalCultures,
getIsAuthenticated,
} = commonStore.auth.actions; } = commonStore.auth.actions;
const { AUTH_KEY } = constants;
/*const Profile = lazy(() => import("./components/pages/Profile")); /*const Profile = lazy(() => import("./components/pages/Profile"));
const ProfileAction = lazy(() => import("./components/pages/ProfileAction")); const ProfileAction = lazy(() => import("./components/pages/ProfileAction"));
@ -43,8 +42,6 @@ const GroupAction = lazy(() => import("./components/pages/GroupAction"));*/
class App extends React.Component { class App extends React.Component {
componentDidMount() { componentDidMount() {
utils.removeTempContent();
const { const {
setModuleInfo, setModuleInfo,
getUser, getUser,
@ -55,14 +52,16 @@ class App extends React.Component {
fetchGroups, fetchGroups,
fetchPeople, fetchPeople,
setIsLoaded, setIsLoaded,
getIsAuthenticated,
} = this.props; } = this.props;
setModuleInfo(); setModuleInfo();
getIsAuthenticated().then((isAuthenticated) => {
const token = localStorage.getItem(AUTH_KEY); if (!isAuthenticated) {
utils.updateTempContent();
if (!token) {
return setIsLoaded(); return setIsLoaded();
} else {
utils.updateTempContent(isAuthenticated);
} }
const requests = [ const requests = [
@ -80,8 +79,10 @@ class App extends React.Component {
toastr.error(e); toastr.error(e);
}) })
.finally(() => { .finally(() => {
utils.updateTempContent();
setIsLoaded(); setIsLoaded();
}); });
});
} }
render() { render() {
@ -156,6 +157,7 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => { const mapDispatchToProps = (dispatch) => {
return { return {
getIsAuthenticated: () => getIsAuthenticated(dispatch),
setModuleInfo: () => { setModuleInfo: () => {
dispatch(setCurrentProductHomePage(config.homepage)); dispatch(setCurrentProductHomePage(config.homepage));
dispatch(setCurrentProductId("f4d98afd-d336-4332-8778-3c6945c81ea0")); dispatch(setCurrentProductId("f4d98afd-d336-4332-8778-3c6945c81ea0"));

View File

@ -7,10 +7,7 @@ import "./custom.scss";
import App from "./App"; import App from "./App";
import * as serviceWorker from "./serviceWorker"; import * as serviceWorker from "./serviceWorker";
import { ErrorBoundary, utils } from "asc-web-common"; import { ErrorBoundary } from "asc-web-common";
const { redirectToDefaultPage } = utils;
redirectToDefaultPage();
ReactDOM.render( ReactDOM.render(
<Provider store={store}> <Provider store={store}>

View File

@ -212,16 +212,5 @@
To begin the development, run `npm start` or `yarn start`. To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<script>
if (localStorage.getItem("asc_auth_key")){
let el = document.getElementById("burger-loader-svg");
let el1 = document.getElementById("logo-loader-svg");
let el2 = document.getElementById("avatar-loader-svg");
el.style.display = "block";
el1.style.display = "block";
el2.style.display = "block";
}
</script>
</body> </body>
</html> </html>

View File

@ -3,7 +3,6 @@ import { Router, Route, Switch } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { import {
store as CommonStore, store as CommonStore,
constants,
history, history,
PrivateRoute, PrivateRoute,
PublicRoute, PublicRoute,
@ -28,23 +27,28 @@ const {
getUser, getUser,
getPortalSettings, getPortalSettings,
getModules, getModules,
getIsAuthenticated,
} = CommonStore.auth.actions; } = CommonStore.auth.actions;
class App extends React.Component { class App extends React.Component {
componentDidMount() { componentDidMount() {
utils.removeTempContent(); const {
getPortalSettings,
const { getPortalSettings, getUser, getModules, setIsLoaded } = this.props; getUser,
getModules,
const { AUTH_KEY } = constants; setIsLoaded,
getIsAuthenticated,
const token = localStorage.getItem(AUTH_KEY); } = this.props;
getIsAuthenticated()
.then((isAuthenticated) => {
if (isAuthenticated) utils.updateTempContent(isAuthenticated);
const requests = []; const requests = [];
if (!isAuthenticated) {
if (!token) {
requests.push(getPortalSettings()); requests.push(getPortalSettings());
} else if (!window.location.pathname.includes("confirm/EmailActivation")) { } else if (
!window.location.pathname.includes("confirm/EmailActivation")
) {
requests.push(getUser()); requests.push(getUser());
requests.push(getPortalSettings()); requests.push(getPortalSettings());
requests.push(getModules()); requests.push(getModules());
@ -55,8 +59,11 @@ class App extends React.Component {
toastr.error(e); toastr.error(e);
}) })
.finally(() => { .finally(() => {
utils.updateTempContent();
setIsLoaded(); setIsLoaded();
}); });
})
.catch((err) => toastr.error(err));
} }
render() { render() {
@ -113,6 +120,7 @@ const mapStateToProps = (state) => {
const mapDispatchToProps = (dispatch) => { const mapDispatchToProps = (dispatch) => {
return { return {
getIsAuthenticated: () => getIsAuthenticated(dispatch),
getPortalSettings: () => getPortalSettings(dispatch), getPortalSettings: () => getPortalSettings(dispatch),
getUser: () => getUser(dispatch), getUser: () => getUser(dispatch),
getModules: () => getModules(dispatch), getModules: () => getModules(dispatch),

View File

@ -2,9 +2,12 @@ import React, { Suspense, lazy, useEffect } from "react";
import { Route, Switch } from "react-router-dom"; import { Route, Switch } from "react-router-dom";
import ConfirmRoute from "../../../helpers/confirmRoute"; import ConfirmRoute from "../../../helpers/confirmRoute";
import { I18nextProvider } from "react-i18next"; import { I18nextProvider } from "react-i18next";
import { Error404, utils } from "asc-web-common"; import { Error404, utils, store, PageLayout, Loaders } from "asc-web-common";
import { createI18N } from "../../../helpers/i18n"; import { createI18N } from "../../../helpers/i18n";
import { connect } from "react-redux";
const { getIsLoaded } = store.auth.selectors;
const i18n = createI18N({ const i18n = createI18N({
page: "Confirm", page: "Confirm",
localesPath: "pages/Confirm", localesPath: "pages/Confirm",
@ -23,13 +26,19 @@ const ChangePhoneForm = lazy(() => import("./sub-components/changePhone"));
const ProfileRemoveForm = lazy(() => import("./sub-components/profileRemove")); const ProfileRemoveForm = lazy(() => import("./sub-components/profileRemove"));
const ChangeOwnerForm = lazy(() => import("./sub-components/changeOwner")); const ChangeOwnerForm = lazy(() => import("./sub-components/changeOwner"));
const Confirm = ({ match }) => { const Confirm = ({ match, isLoaded }) => {
useEffect(() => { useEffect(() => {
changeLanguage(i18n); changeLanguage(i18n);
}, []); }, []);
//console.log("Confirm render"); //console.log("Confirm render");
return ( return (
!isLoaded ? <PageLayout>
<PageLayout.SectionBody>
<Loaders.Rectangle height="90vh"/>
</PageLayout.SectionBody>
</PageLayout> :
<I18nextProvider i18n={i18n}> <I18nextProvider i18n={i18n}>
<Suspense fallback={null}> <Suspense fallback={null}>
<Switch> <Switch>
@ -80,4 +89,10 @@ const Confirm = ({ match }) => {
); );
}; };
export default Confirm; function mapStateToProps(state) {
return {
isLoaded: getIsLoaded(state)
};
}
export default connect(mapStateToProps)(Confirm);

View File

@ -5,13 +5,14 @@ import { Loader } from "asc-web-components";
import { PageLayout } from "asc-web-common"; import { PageLayout } from "asc-web-common";
import { connect } from "react-redux"; import { connect } from "react-redux";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { store } from "asc-web-common"; import { store, utils as commonUtils } from "asc-web-common";
import { changeEmail } from "../../../../store/confirm/actions"; import { changeEmail } from "../../../../store/confirm/actions";
const { logout } = store.auth.actions; const { logout } = store.auth.actions;
const { tryRedirectTo } = commonUtils;
class ActivateEmail extends React.PureComponent { class ActivateEmail extends React.PureComponent {
componentDidMount() { componentDidMount() {
const { history, logout, changeEmail, linkData } = this.props; const { logout, changeEmail, linkData } = this.props;
const [email, uid, key] = [ const [email, uid, key] = [
linkData.email, linkData.email,
linkData.uid, linkData.uid,
@ -20,11 +21,11 @@ class ActivateEmail extends React.PureComponent {
logout(); logout();
changeEmail(uid, email, key) changeEmail(uid, email, key)
.then((res) => { .then((res) => {
history.push(`/login/confirmed-email=${email}`); tryRedirectTo(`/login/confirmed-email=${email}`);
}) })
.catch((e) => { .catch((e) => {
// console.log('activate email error', e); // console.log('activate email error', e);
history.push(`/login/error=${e}`); tryRedirectTo(`/login/error=${e}`);
}); });
} }

View File

@ -19,7 +19,7 @@ import {
activateConfirmUser, activateConfirmUser,
} from "../../../../store/confirm/actions"; } from "../../../../store/confirm/actions";
const { EmployeeActivationStatus } = constants; const { EmployeeActivationStatus } = constants;
const { createPasswordHash } = commonUtils; const { createPasswordHash, tryRedirectTo } = commonUtils;
const inputWidth = "400px"; const inputWidth = "400px";
const ConfirmContainer = styled.div` const ConfirmContainer = styled.div`
@ -82,7 +82,7 @@ class Confirm extends React.PureComponent {
onSubmit = (e) => { onSubmit = (e) => {
this.setState({ isLoading: true }, function () { this.setState({ isLoading: true }, function () {
const { activateConfirmUser, history, hashSettings } = this.props; const { activateConfirmUser, hashSettings, defaultPage } = this.props;
this.setState({ errorText: "" }); this.setState({ errorText: "" });
@ -131,7 +131,7 @@ class Confirm extends React.PureComponent {
this.state.userId, this.state.userId,
EmployeeActivationStatus.Activated EmployeeActivationStatus.Activated
) )
.then(() => history.push("/")) .then(() => tryRedirectTo(defaultPage))
.catch((error) => { .catch((error) => {
console.error("activate error", error); console.error("activate error", error);
this.setState({ this.setState({
@ -344,6 +344,7 @@ function mapStateToProps(state) {
settings: state.auth.settings.passwordSettings, settings: state.auth.settings.passwordSettings,
greetingTitle: state.auth.settings.greetingSettings, greetingTitle: state.auth.settings.greetingSettings,
hashSettings: state.auth.settings.hashSettings, hashSettings: state.auth.settings.hashSettings,
defaultPage: state.auth.settings.defaultPage,
}; };
} }

View File

@ -2,10 +2,11 @@ import React from "react";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { withTranslation } from "react-i18next"; import { withTranslation } from "react-i18next";
import { Loader } from "asc-web-components"; import { Loader } from "asc-web-components";
import { PageLayout } from "asc-web-common"; import { PageLayout, utils as commonUtils } from "asc-web-common";
import { connect } from "react-redux"; import { connect } from "react-redux";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { changeEmail } from "../../../../store/confirm/actions"; import { changeEmail } from "../../../../store/confirm/actions";
const { tryRedirectTo } = commonUtils;
class ChangeEmail extends React.PureComponent { class ChangeEmail extends React.PureComponent {
componentDidMount() { componentDidMount() {
@ -15,29 +16,33 @@ class ChangeEmail extends React.PureComponent {
changeEmail(userId, email, key) changeEmail(userId, email, key)
.then((res) => { .then((res) => {
console.log("change client email success", res); console.log("change client email success", res);
window.location.href = `${window.location.origin}/products/people/view/@self?email_change=success`; tryRedirectTo(
`${window.location.origin}/products/people/view/@self?email_change=success`
);
}) })
.catch((e) => { .catch((e) => {
console.log("change client email error", e); console.log("change client email error", e);
window.location.href = `${window.location.origin}/error=${e}`; tryRedirectTo(`${window.location.origin}/error=${e}`);
}); });
} }
} }
componentDidUpdate() { componentDidUpdate() {
const { changeEmail, userId, isLoaded, linkData } = this.props; const { changeEmail, userId, isLoaded, linkData, defaultPage } = this.props;
if (isLoaded) { if (isLoaded) {
const [email, key] = [linkData.email, linkData.confirmHeader]; const [email, key] = [linkData.email, linkData.confirmHeader];
changeEmail(userId, email, key) changeEmail(userId, email, key)
.then((res) => { .then((res) => {
console.log("change client email success", res); console.log("change client email success", res);
window.location.href = `${window.location.origin}/products/people/view/@self?email_change=success`; tryRedirectTo(
`${window.location.origin}/products/people/view/@self?email_change=success`
);
}) })
.catch((e) => { .catch((e) => {
console.log("change client email error", e); console.log("change client email error", e);
}); });
} else { } else {
window.location.href = "/"; tryRedirectTo(defaultPage);
} }
} }
@ -63,6 +68,7 @@ function mapStateToProps(state) {
return { return {
isLoaded: state.auth.isLoaded, isLoaded: state.auth.isLoaded,
userId: state.auth.user.id, userId: state.auth.user.id,
defaultPage: state.auth.settings.defaultPage,
}; };
} }

View File

@ -4,7 +4,8 @@ import { withTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import styled from "styled-components"; import styled from "styled-components";
import { Button, Text, toastr } from "asc-web-components"; import { Button, Text, toastr } from "asc-web-components";
import { PageLayout } from "asc-web-common"; import { PageLayout, utils as commonUtils } from "asc-web-common";
const { tryRedirectTo } = commonUtils;
const BodyStyle = styled.div` const BodyStyle = styled.div`
margin-top: 70px; margin-top: 70px;
@ -58,11 +59,11 @@ class Form extends React.PureComponent {
}; };
onRedirect = () => { onRedirect = () => {
this.props.history.push("/"); tryRedirectTo(this.props.defaultPage);
}; };
onCancelClick = () => { onCancelClick = () => {
this.props.history.push("/"); tryRedirectTo(this.props.defaultPage);
}; };
render() { render() {
@ -126,7 +127,10 @@ const ChangePasswordForm = (props) => (
); );
function mapStateToProps(state) { function mapStateToProps(state) {
return { greetingTitle: state.auth.settings.greetingSettings }; return {
greetingTitle: state.auth.settings.greetingSettings,
defaultPage: state.auth.settings.defaultPage,
};
} }
export default connect( export default connect(

View File

@ -19,7 +19,7 @@ import {
changePassword, changePassword,
} from "../../../../store/confirm/actions"; } from "../../../../store/confirm/actions";
const { createPasswordHash } = commonUtils; const { createPasswordHash, tryRedirectTo } = commonUtils;
const { logout } = store.auth.actions; const { logout } = store.auth.actions;
const BodyStyle = styled.form` const BodyStyle = styled.form`
@ -80,7 +80,7 @@ class Form extends React.PureComponent {
onSubmit = (e) => { onSubmit = (e) => {
this.setState({ isLoading: true }, function () { this.setState({ isLoading: true }, function () {
const { userId, password, key } = this.state; const { userId, password, key } = this.state;
const { history, changePassword, hashSettings } = this.props; const { changePassword, hashSettings, defaultPage } = this.props;
let hasError = false; let hasError = false;
if (!this.state.passwordValid) { if (!this.state.passwordValid) {
@ -99,8 +99,8 @@ class Form extends React.PureComponent {
changePassword(userId, hash, key) changePassword(userId, hash, key)
.then(() => this.props.logout()) .then(() => this.props.logout())
.then(() => { .then(() => {
history.push("/");
toastr.success(this.props.t("ChangePasswordSuccess")); toastr.success(this.props.t("ChangePasswordSuccess"));
tryRedirectTo(defaultPage);
}) })
.catch((error) => { .catch((error) => {
toastr.error(this.props.t(`${error}`)); toastr.error(this.props.t(`${error}`));
@ -110,10 +110,10 @@ class Form extends React.PureComponent {
}; };
componentDidMount() { componentDidMount() {
const { getConfirmationInfo, history } = this.props; const { getConfirmationInfo, defaultPage } = this.props;
getConfirmationInfo(this.state.key).catch((error) => { getConfirmationInfo(this.state.key).catch((error) => {
toastr.error(this.props.t(`${error}`)); toastr.error(this.props.t(`${error}`));
history.push("/"); tryRedirectTo(defaultPage);
}); });
window.addEventListener("keydown", this.onKeyPress); window.addEventListener("keydown", this.onKeyPress);
@ -221,6 +221,7 @@ function mapStateToProps(state) {
isAuthenticated: state.auth.isAuthenticated, isAuthenticated: state.auth.isAuthenticated,
greetingTitle: state.auth.settings.greetingSettings, greetingTitle: state.auth.settings.greetingSettings,
hashSettings: state.auth.settings.hashSettings, hashSettings: state.auth.settings.hashSettings,
defaultPage: state.auth.settings.defaultPage,
}; };
} }

View File

@ -50,7 +50,7 @@ const PhoneForm = (props) => {
const buttonTranslation = `Enter number`; const buttonTranslation = `Enter number`;
const onSubmit = () => { const onSubmit = () => {
console.log("onSubmit CHANGE"); console.log("onSubmit CHANGE"); //TODO: Why do nothing?
}; };
const onKeyPress = (target) => { const onKeyPress = (target) => {

View File

@ -19,7 +19,7 @@ import {
createConfirmUser, createConfirmUser,
} from "../../../../store/confirm/actions"; } from "../../../../store/confirm/actions";
const { logout, login } = store.auth.actions; const { logout, login } = store.auth.actions;
const { createPasswordHash } = commonUtils; const { createPasswordHash, tryRedirectTo } = commonUtils;
const inputWidth = "400px"; const inputWidth = "400px";
const ConfirmContainer = styled.div` const ConfirmContainer = styled.div`
@ -89,7 +89,7 @@ class Confirm extends React.PureComponent {
onSubmit = () => { onSubmit = () => {
this.setState({ isLoading: true }, () => { this.setState({ isLoading: true }, () => {
const { history, createConfirmUser, linkData, hashSettings } = this.props; const { defaultPage, createConfirmUser, linkData, hashSettings } = this.props;
const isVisitor = parseInt(linkData.emplType) === 2; const isVisitor = parseInt(linkData.emplType) === 2;
this.setState({ errorText: "" }); this.setState({ errorText: "" });
@ -142,7 +142,7 @@ class Confirm extends React.PureComponent {
createConfirmUser(registerData, loginData, this.state.key) createConfirmUser(registerData, loginData, this.state.key)
.then(() => { .then(() => {
toastr.success("User has been created successfully"); toastr.success("User has been created successfully");
return history.push("/"); tryRedirectTo(defaultPage);
}) })
.catch((error) => { .catch((error) => {
console.error("confirm error", error); console.error("confirm error", error);
@ -368,6 +368,7 @@ function mapStateToProps(state) {
settings: state.auth.settings.passwordSettings, settings: state.auth.settings.passwordSettings,
greetingTitle: state.auth.settings.greetingSettings, greetingTitle: state.auth.settings.greetingSettings,
hashSettings: state.auth.settings.hashSettings, hashSettings: state.auth.settings.hashSettings,
defaultPage: state.auth.settings.defaultPage
}; };
} }
@ -375,5 +376,5 @@ export default connect(mapStateToProps, {
getConfirmationInfo, getConfirmationInfo,
createConfirmUser, createConfirmUser,
login, login,
logout, logout
})(withRouter(withTranslation()(CreateUserForm))); })(withRouter(withTranslation()(CreateUserForm)));

View File

@ -4,9 +4,9 @@ import { ValidationResult } from "./../helpers/constants";
import { Loader } from "asc-web-components"; import { Loader } from "asc-web-components";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { api, constants, utils, PageLayout } from "asc-web-common"; import { api, utils, PageLayout, store } from "asc-web-common";
const { isAuthenticated } = store.auth.selectors;
const { checkConfirmLink } = api.user; const { checkConfirmLink } = api.user;
const { AUTH_KEY } = constants;
const { getObjectByLocation } = utils; const { getObjectByLocation } = utils;
class ConfirmRoute extends React.Component { class ConfirmRoute extends React.Component {
@ -19,14 +19,14 @@ class ConfirmRoute extends React.Component {
} }
componentDidMount() { componentDidMount() {
const { forUnauthorized, history } = this.props; const { forUnauthorized, history, isAuthenticated } = this.props;
if (forUnauthorized && localStorage.getItem(AUTH_KEY)) if (forUnauthorized && isAuthenticated)
return history.push( return history.push(
`/error=Access error. You should be unauthorized for performing this action` `/error=Access error. You should be unauthorized for performing this action`
); );
const { location, isAuthenticated } = this.props; const { location } = this.props;
const { search } = location; const { search } = location;
const queryParams = getObjectByLocation(location); const queryParams = getObjectByLocation(location);
@ -100,7 +100,7 @@ class ConfirmRoute extends React.Component {
function mapStateToProps(state) { function mapStateToProps(state) {
return { return {
isAuthenticated: state.auth.isAuthenticated, isAuthenticated: isAuthenticated(state)
}; };
} }

View File

@ -5,10 +5,7 @@ import store from "./store/store";
import "./custom.scss"; import "./custom.scss";
import App from "./App"; import App from "./App";
import * as serviceWorker from "./serviceWorker"; import * as serviceWorker from "./serviceWorker";
import { ErrorBoundary, utils } from "asc-web-common"; import { ErrorBoundary } from "asc-web-common";
const { redirectToDefaultPage } = utils;
redirectToDefaultPage();
ReactDOM.render( ReactDOM.render(
<Provider store={store}> <Provider store={store}>

View File

@ -30,9 +30,27 @@ export function createConfirmUser(registerData, loginData, key) {
return (dispatch) => { return (dispatch) => {
return api.people return api.people
.createUser(data, key) .createUser(data, key)
.then((user) => dispatch(setCurrentUser(user))) .then((user) => {
.then(() => api.user.login(loginData.userName, loginData.passwordHash)) dispatch(setCurrentUser(user));
.then(() => loadInitInfo(dispatch)); })
.then(() => {
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
login(
loginData.userName,
loginData.passwordHash
)(dispatch)
.then(() => {
resolve(loadInitInfo(dispatch));
})
.catch((e) => {
reject(e);
});
}, 1000);
});
return promise;
});
}; };
} }
@ -56,7 +74,22 @@ export function activateConfirmUser(
return api.people.updateActivationStatus(activationStatus, userId, key); return api.people.updateActivationStatus(activationStatus, userId, key);
}) })
.then((data) => { .then((data) => {
return dispatch(login(loginData.userName, loginData.passwordHash)); const promise = new Promise((resolve, reject) => {
setTimeout(() => {
login(
data.userName,
data.passwordHash
)(dispatch)
.then(() => {
resolve(loadInitInfo(dispatch));
})
.catch((e) => {
reject(e);
});
}, 1000);
});
return promise;
}) })
.then((data) => { .then((data) => {
return api.people.updateUser(changedData); return api.people.updateUser(changedData);

View File

@ -1,6 +1,6 @@
{ {
"name": "asc-web-common", "name": "asc-web-common",
"version": "1.0.282", "version": "1.0.285",
"description": "Ascensio System SIA common components and solutions library", "description": "Ascensio System SIA common components and solutions library",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"files": [ "files": [

View File

@ -1,5 +1,4 @@
import axios from "axios"; import axios from "axios";
import { AUTH_KEY } from "../constants";
//import history from "../history"; //import history from "../history";
const PREFIX = "api"; const PREFIX = "api";
@ -16,8 +15,6 @@ const client = axios.create({
timeout: 30000, // default is `0` (no timeout) timeout: 30000, // default is `0` (no timeout)
}); });
setAuthorizationToken(localStorage.getItem(AUTH_KEY));
client.interceptors.response.use( client.interceptors.response.use(
(response) => { (response) => {
return response; return response;
@ -25,7 +22,7 @@ client.interceptors.response.use(
(error) => { (error) => {
switch (true) { switch (true) {
case error.response.status === 401: case error.response.status === 401:
setAuthorizationToken(); setWithCredentialsStatus(false);
window.location.href = "/login"; window.location.href = "/login";
break; break;
case error.response.status === 402: case error.response.status === 402:
@ -41,13 +38,8 @@ client.interceptors.response.use(
} }
); );
export function setAuthorizationToken(token) { export function setWithCredentialsStatus(state) {
client.defaults.withCredentials = true; client.defaults.withCredentials = state;
if (token) {
localStorage.setItem(AUTH_KEY, true);
} else {
localStorage.clear();
}
} }
export function setClientBasePath(path) { export function setClientBasePath(path) {

View File

@ -1,4 +1,4 @@
import { request, setAuthorizationToken } from "../client"; import { request, setWithCredentialsStatus } from "../client";
export function login(userName, passwordHash) { export function login(userName, passwordHash) {
const data = { const data = {
@ -10,9 +10,6 @@ export function login(userName, passwordHash) {
method: "post", method: "post",
url: "/authentication.json", url: "/authentication.json",
data, data,
}).then((tokenData) => {
setAuthorizationToken(true);
return Promise.resolve(tokenData);
}); });
} }
@ -20,9 +17,6 @@ export function logout() {
return request({ return request({
method: "post", method: "post",
url: "/authentication/logout", url: "/authentication/logout",
}).then(() => {
setAuthorizationToken();
return Promise.resolve();
}); });
} }
@ -33,3 +27,14 @@ export function checkConfirmLink(data) {
data, data,
}); });
} }
export function checkIsAuthenticated() {
return request({
method: "get",
url: "/authentication",
withCredentials: true,
}).then((state) => {
setWithCredentialsStatus(state);
return state;
});
}

View File

@ -104,7 +104,7 @@ class NavMenu extends React.Component {
const isAsideAvailable = !!asideContent; const isAsideAvailable = !!asideContent;
console.log("NavMenu render", this.state, this.props); //console.log("NavMenu render", this.state, this.props);
return ( return (
<StyledContainer> <StyledContainer>

View File

@ -81,6 +81,9 @@ class PageLayoutComponent extends React.Component {
isArticleVisible: isArticleVisibleAndPinned, isArticleVisible: isArticleVisibleAndPinned,
isArticlePinned: isArticleVisibleAndPinned, isArticlePinned: isArticleVisibleAndPinned,
}; };
this.timeoutHandler = null;
this.intervalHandler = null;
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
@ -103,6 +106,11 @@ class PageLayoutComponent extends React.Component {
"orientationchange", "orientationchange",
this.orientationChangeHandler this.orientationChangeHandler
); );
if(this.intervalHandler)
clearInterval(this.intervalHandler);
if(this.timeoutHandler)
clearTimeout(this.timeoutHandler);
} }
orientationChangeHandler = () => { orientationChangeHandler = () => {
@ -123,20 +131,22 @@ class PageLayoutComponent extends React.Component {
const intervalTime = 100; const intervalTime = 100;
const endTimeoutTime = 1000; const endTimeoutTime = 1000;
let interval, timeout, lastInnerHeight, noChangeCount; let lastInnerHeight, noChangeCount;
const updateHeight = () => { const updateHeight = () => {
clearInterval(interval); if(this.intervalHandler)
clearTimeout(timeout); clearInterval(this.intervalHandler);
if(this.timeoutHandler)
clearTimeout(this.timeoutHandler);
interval = null; this.intervalHandler = null;
timeout = null; this.timeoutHandler = null;
const vh = (window.innerHeight - 57) * 0.01; const vh = (window.innerHeight - 57) * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`); document.documentElement.style.setProperty("--vh", `${vh}px`);
}; };
interval = setInterval(() => { this.intervalHandler = setInterval(() => {
if (window.innerHeight === lastInnerHeight) { if (window.innerHeight === lastInnerHeight) {
noChangeCount++; noChangeCount++;
@ -149,7 +159,7 @@ class PageLayoutComponent extends React.Component {
} }
}); });
timeout = setTimeout(() => { this.timeoutHandler = setTimeout(() => {
updateHeight(); updateHeight();
}, endTimeoutTime); }, endTimeoutTime);
}; };

View File

@ -86,6 +86,11 @@ class SectionBody extends React.Component {
this.focusRef.current.focus(); this.focusRef.current.focus();
} }
componentWillUnmount() {
this.focusRef = null;
this.scrollRef = null;
}
render() { render() {
//console.log("PageLayout SectionBody render"); //console.log("PageLayout SectionBody render");
const { const {

View File

@ -3,16 +3,17 @@ import React from "react";
import { Redirect, Route } from "react-router-dom"; import { Redirect, Route } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
//import { Loader } from "asc-web-components"; //import { Loader } from "asc-web-components";
//import PageLayout from "../PageLayout"; import PageLayout from "../PageLayout";
import { getCurrentUser, isAdmin, isMe } from "../../store/auth/selectors.js"; import { getCurrentUser, getIsLoaded, isAdmin, isAuthenticated, isMe } from "../../store/auth/selectors.js";
import { AUTH_KEY } from "../../constants";
import { Error401, Error404 } from "../../pages/errors"; import { Error401, Error404 } from "../../pages/errors";
import isEmpty from "lodash/isEmpty"; import RectangleLoader from "../Loaders/RectangleLoader/RectangleLoader";
//import isEmpty from "lodash/isEmpty";
const PrivateRoute = ({ component: Component, ...rest }) => { const PrivateRoute = ({ component: Component, ...rest }) => {
const { const {
isAdmin, isAdmin,
isAuthenticated, isAuthenticated,
isLoaded,
restricted, restricted,
allowForMe, allowForMe,
user, user,
@ -21,7 +22,7 @@ const PrivateRoute = ({ component: Component, ...rest }) => {
const { userId } = computedMatch.params; const { userId } = computedMatch.params;
const renderComponent = (props) => { const renderComponent = (props) => {
if (!isAuthenticated) { if (isLoaded && !isAuthenticated) {
console.log("PrivateRoute render Redirect to login", rest); console.log("PrivateRoute render Redirect to login", rest);
return ( return (
<Redirect <Redirect
@ -33,11 +34,21 @@ const PrivateRoute = ({ component: Component, ...rest }) => {
); );
} }
const userLoaded = !isEmpty(user); if(!isLoaded) {
if (!userLoaded) { return (
return <Component {...props} />; <PageLayout>
<PageLayout.SectionBody>
<RectangleLoader height="90vh"/>
</PageLayout.SectionBody>
</PageLayout>
);
} }
// const userLoaded = !isEmpty(user);
// if (!userLoaded) {
// return <Component {...props} />;
// }
// if (!userLoaded) { // if (!userLoaded) {
// console.log("PrivateRoute render Loader", rest); // console.log("PrivateRoute render Loader", rest);
// return ( // return (
@ -76,14 +87,11 @@ const PrivateRoute = ({ component: Component, ...rest }) => {
}; };
function mapStateToProps(state) { function mapStateToProps(state) {
const { isLoaded, isAuthenticated } = state.auth;
return { return {
isAdmin: isAdmin(state), isAdmin: isAdmin(state),
user: getCurrentUser(state), user: getCurrentUser(state),
isAuthenticated: !( isAuthenticated: isAuthenticated(state),
!localStorage.getItem(AUTH_KEY) || isLoaded: getIsLoaded(state)
(isLoaded && !isAuthenticated)
),
}; };
} }

View File

@ -1,16 +1,26 @@
/* eslint-disable react/prop-types */ /* eslint-disable react/prop-types */
import React from "react"; import React from "react";
import { Redirect, Route } from "react-router-dom"; import { Redirect, Route } from "react-router-dom";
import { AUTH_KEY } from "../../constants";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { getIsLoaded, isAuthenticated } from "../../store/auth/selectors";
import PageLayout from "../PageLayout";
import RectangleLoader from "../Loaders/RectangleLoader/RectangleLoader";
export const PublicRoute = ({ component: Component, ...rest }) => { export const PublicRoute = ({ component: Component, ...rest }) => {
const token = localStorage.getItem(AUTH_KEY); const { wizardToken, wizardCompleted, isAuthenticated, isLoaded } = rest;
const { wizardToken, wizardCompleted } = rest;
const renderComponent = (props) => { const renderComponent = (props) => {
if (token) { if(!isLoaded) {
return (
<PageLayout>
<PageLayout.SectionBody>
<RectangleLoader height="90vh"/>
</PageLayout.SectionBody>
</PageLayout>
);
}
if (isAuthenticated) {
return ( return (
<Redirect <Redirect
to={{ to={{
@ -38,9 +48,14 @@ export const PublicRoute = ({ component: Component, ...rest }) => {
}; };
function mapStateToProps(state) { function mapStateToProps(state) {
const { settings } = state.auth;
const {wizardToken, wizardCompleted} = settings;
return { return {
wizardToken: state.auth.settings.wizardToken, isAuthenticated: isAuthenticated(state),
wizardCompleted: state.auth.settings.wizardCompleted, isLoaded: getIsLoaded(state),
wizardToken,
wizardCompleted,
}; };
} }

View File

@ -1,4 +1,3 @@
export const AUTH_KEY = "asc_auth_key";
export const LANGUAGE = "language"; export const LANGUAGE = "language";
export const ARTICLE_PINNED_KEY = "asc_article_pinned_key"; export const ARTICLE_PINNED_KEY = "asc_article_pinned_key";

View File

@ -10,9 +10,8 @@ import {
Link, Link,
toastr, toastr,
Checkbox, Checkbox,
HelpButton,
PasswordInput, PasswordInput,
FieldContainer, FieldContainer
} from "asc-web-components"; } from "asc-web-components";
import PageLayout from "../../components/PageLayout"; import PageLayout from "../../components/PageLayout";
import { connect } from "react-redux"; import { connect } from "react-redux";
@ -23,12 +22,11 @@ import ForgotPasswordModalDialog from "./sub-components/forgot-password-modal-di
import { import {
login, login,
setIsLoaded, setIsLoaded,
reloadPortalSettings, reloadPortalSettings
} from "../../store/auth/actions"; } from "../../store/auth/actions";
import { sendInstructionsToChangePassword } from "../../api/people"; import { sendInstructionsToChangePassword } from "../../api/people";
import Register from "./sub-components/register-container"; import Register from "./sub-components/register-container";
import { createPasswordHash } from "../../utils"; import { createPasswordHash, tryRedirectTo } from "../../utils";
import { redirectToDefaultPage } from "../../utils";
const { getLanguage } = store.auth.selectors; const { getLanguage } = store.auth.selectors;
const LoginContainer = styled.div` const LoginContainer = styled.div`
display: flex; display: flex;
@ -75,8 +73,7 @@ const LoginContainer = styled.div`
padding: 14px 0; padding: 14px 0;
.login-checkbox-wrapper { .login-checkbox-wrapper {
position: absolute; display: flex;
display: inline-flex;
.login-checkbox { .login-checkbox {
float: left; float: left;
@ -84,23 +81,11 @@ const LoginContainer = styled.div`
font-size: 12px; font-size: 12px;
} }
} }
.login-tooltip {
display: inline-flex;
@media (min-width: 1025px) {
margin-left: 8px;
margin-top: 4px;
}
@media (max-width: 1024px) {
padding: 4px 8px 8px 8px;
}
}
} }
.login-link { .login-link {
float: right; line-height: 18px;
line-height: 16px; margin-left: auto;
} }
} }
@ -126,7 +111,8 @@ const LoginContainer = styled.div`
const LoginFormWrapper = styled.div` const LoginFormWrapper = styled.div`
display: grid; display: grid;
grid-template-rows: ${props => props.enabledJoin ? css`1fr 66px` : css`1fr`}; grid-template-rows: ${(props) =>
props.enabledJoin ? css`1fr 66px` : css`1fr`};
width: 100%; width: 100%;
height: calc(100vh-56px); height: calc(100vh-56px);
`; `;
@ -211,7 +197,12 @@ class Form extends Component {
onSubmit = () => { onSubmit = () => {
const { errorText, identifier, password } = this.state; const { errorText, identifier, password } = this.state;
const { login, setIsLoaded, hashSettings } = this.props; const {
login,
setIsLoaded,
hashSettings,
defaultPage
} = this.props;
errorText && this.setState({ errorText: "" }); errorText && this.setState({ errorText: "" });
let hasError = false; let hasError = false;
@ -237,12 +228,17 @@ class Form extends Component {
login(userName, hash) login(userName, hash)
.then(() => { .then(() => {
if (!redirectToDefaultPage()) { if (!tryRedirectTo(defaultPage)) {
setIsLoaded(true); setIsLoaded(true);
} }
}) })
.catch((error) => { .catch((error) => {
this.setState({ errorText: error, isLoading: false }); this.setState({
errorText: error,
identifierValid: !error,
passwordValid: !error,
isLoading: false,
});
}); });
}; };
@ -250,8 +246,8 @@ class Form extends Component {
const { const {
match, match,
t, t,
hashSettings, hashSettings, // eslint-disable-line react/prop-types
reloadPortalSettings, reloadPortalSettings, // eslint-disable-line react/prop-types
organizationName, organizationName,
} = this.props; } = this.props;
const { error, confirmedEmail } = match.params; const { error, confirmedEmail } = match.params;
@ -315,7 +311,7 @@ class Form extends Component {
isVertical={true} isVertical={true}
labelVisible={false} labelVisible={false}
hasError={!identifierValid} hasError={!identifierValid}
errorMessage={t("RequiredFieldMessage")} errorMessage={errorText ? errorText : t("RequiredFieldMessage")} //TODO: Add wrong login server error
> >
<TextInput <TextInput
id="login" id="login"
@ -337,7 +333,7 @@ class Form extends Component {
isVertical={true} isVertical={true}
labelVisible={false} labelVisible={false}
hasError={!passwordValid} hasError={!passwordValid}
errorMessage={t("RequiredFieldMessage")} errorMessage={errorText ? "" : t("RequiredFieldMessage")} //TODO: Add wrong password server error
> >
<PasswordInput <PasswordInput
simpleView={true} simpleView={true}
@ -365,15 +361,13 @@ class Form extends Component {
onChange={this.onChangeCheckbox} onChange={this.onChangeCheckbox}
label={<Text fontSize="13px">{t("Remember")}</Text>} label={<Text fontSize="13px">{t("Remember")}</Text>}
/> />
<HelpButton {/*<HelpButton
className="login-tooltip" className="login-tooltip"
helpButtonHeaderContent={t("CookieSettingsTitle")} helpButtonHeaderContent={t("CookieSettingsTitle")}
tooltipContent={ tooltipContent={
<Text fontSize="12px">{t("RememberHelper")}</Text> <Text fontSize="12px">{t("RememberHelper")}</Text>
} }
/> />*/}
</div>
<Link <Link
fontSize="13px" fontSize="13px"
color="#316DAA" color="#316DAA"
@ -385,6 +379,7 @@ class Form extends Component {
{t("ForgotPassword")} {t("ForgotPassword")}
</Link> </Link>
</div> </div>
</div>
{openDialog && ( {openDialog && (
<ForgotPasswordModalDialog <ForgotPasswordModalDialog
@ -417,9 +412,11 @@ class Form extends Component {
{t("MessageEmailConfirmed")} {t("MessageAuthorize")} {t("MessageEmailConfirmed")} {t("MessageAuthorize")}
</Text> </Text>
)} )}
{/* TODO: old error indication
<Text fontSize="14px" color="#c30"> <Text fontSize="14px" color="#c30">
{errorText} {errorText}
</Text> </Text> */}
{socialButtons.length ? ( {socialButtons.length ? (
<Box displayProp="flex" alignItems="center"> <Box displayProp="flex" alignItems="center">
@ -450,6 +447,7 @@ Form.propTypes = {
socialButtons: PropTypes.array, socialButtons: PropTypes.array,
organizationName: PropTypes.string, organizationName: PropTypes.string,
homepage: PropTypes.string, homepage: PropTypes.string,
defaultPage: PropTypes.string,
}; };
Form.defaultProps = { Form.defaultProps = {
@ -486,21 +484,29 @@ LoginForm.propTypes = {
}; };
function mapStateToProps(state) { function mapStateToProps(state) {
const { isLoaded, settings } = state.auth; const { isLoaded, settings, isAuthenticated } = state.auth;
const { greetingSettings, organizationName, hashSettings, enabledJoin } = settings; const {
greetingSettings,
organizationName,
hashSettings,
enabledJoin,
defaultPage
} = settings;
return { return {
isAuthenticated,
isLoaded, isLoaded,
organizationName, organizationName,
language: getLanguage(state), language: getLanguage(state),
greetingTitle: greetingSettings, greetingTitle: greetingSettings,
hashSettings, hashSettings,
enabledJoin enabledJoin,
defaultPage
}; };
} }
export default connect(mapStateToProps, { export default connect(mapStateToProps, {
login, login,
setIsLoaded, setIsLoaded,
reloadPortalSettings, reloadPortalSettings
})(withRouter(LoginForm)); })(withRouter(LoginForm));

View File

@ -10,6 +10,9 @@ import { connect } from "react-redux";
import i18n from "../i18n"; import i18n from "../i18n";
const StyledRegister = styled(Box)` const StyledRegister = styled(Box)`
display: flex;
align-items: center;
justify-content: center;
z-index: 184; z-index: 184;
width: 100%; width: 100%;
height: 66px; height: 66px;
@ -60,9 +63,7 @@ const Register = ({ t }) => {
return ( return (
<> <>
<StyledRegister onClick={onRegisterClick}> <StyledRegister onClick={onRegisterClick}>
<Text color="#316DAA" textAlign="center"> <Text color="#316DAA">{t("Register")}</Text>
{t("Register")}
</Text>
</StyledRegister> </StyledRegister>
{visible && ( {visible && (

View File

@ -1,4 +1,6 @@
import { default as api } from "../../api"; import { default as api } from "../../api";
import { setWithCredentialsStatus } from "../../api/client";
import history from "../../history";
export const LOGIN_POST = "LOGIN_POST"; export const LOGIN_POST = "LOGIN_POST";
export const SET_CURRENT_USER = "SET_CURRENT_USER"; export const SET_CURRENT_USER = "SET_CURRENT_USER";
@ -17,6 +19,7 @@ export const SET_CURRENT_PRODUCT_HOME_PAGE = "SET_CURRENT_PRODUCT_HOME_PAGE";
export const SET_GREETING_SETTINGS = "SET_GREETING_SETTINGS"; export const SET_GREETING_SETTINGS = "SET_GREETING_SETTINGS";
export const SET_CUSTOM_NAMES = "SET_CUSTOM_NAMES"; export const SET_CUSTOM_NAMES = "SET_CUSTOM_NAMES";
export const SET_WIZARD_COMPLETED = "SET_WIZARD_COMPLETED"; export const SET_WIZARD_COMPLETED = "SET_WIZARD_COMPLETED";
export const SET_IS_AUTHENTICATED = "SET_IS_AUTHENTICATED";
export function setCurrentUser(user) { export function setCurrentUser(user) {
return { return {
@ -128,13 +131,30 @@ export function setWizardComplete() {
}; };
} }
export function setIsAuthenticated(isAuthenticated) {
return {
type: SET_IS_AUTHENTICATED,
isAuthenticated,
};
}
export function getUser(dispatch) { export function getUser(dispatch) {
return api.people return api.people
.getUser() .getUser()
.then((user) => dispatch(setCurrentUser(user))) .then((user) => dispatch(setCurrentUser(user)))
.then(() => dispatch(setIsAuthenticated(true)))
.catch((err) => dispatch(setCurrentUser({}))); .catch((err) => dispatch(setCurrentUser({})));
} }
export function getIsAuthenticated(dispatch) {
return api.user
.checkIsAuthenticated()
.then((success) => {
dispatch(setIsAuthenticated(success));
return success;
});
}
export function getPortalSettings(dispatch) { export function getPortalSettings(dispatch) {
return api.settings.getSettings().then((settings) => { return api.settings.getSettings().then((settings) => {
const { passwordHash: hashSettings, ...otherSettings } = settings; const { passwordHash: hashSettings, ...otherSettings } = settings;
@ -176,16 +196,22 @@ export function login(user, hash) {
return api.user return api.user
.login(user, hash) .login(user, hash)
.then(() => dispatch(setIsLoaded(false))) .then(() => dispatch(setIsLoaded(false)))
.then(() => {
setWithCredentialsStatus(true);
return dispatch(setIsAuthenticated(true));
})
.then(() => getUserInfo(dispatch)); .then(() => getUserInfo(dispatch));
}; };
} }
export function logout() { export function logout() {
return (dispatch) => { return (dispatch) => {
return api.user return api.user.logout().then(() => {
.logout() setWithCredentialsStatus(false);
.then(() => dispatch(setLogout())) dispatch(setLogout());
.then(() => dispatch(setIsLoaded(true)));
history.push("/login");
});
}; };
} }

View File

@ -15,9 +15,9 @@ import {
SET_GREETING_SETTINGS, SET_GREETING_SETTINGS,
SET_CUSTOM_NAMES, SET_CUSTOM_NAMES,
SET_WIZARD_COMPLETED, SET_WIZARD_COMPLETED,
SET_IS_AUTHENTICATED,
} from "./actions"; } from "./actions";
import isEmpty from "lodash/isEmpty"; import { LANGUAGE } from "../../constants";
import { LANGUAGE, AUTH_KEY } from "../../constants";
const initialState = { const initialState = {
isAuthenticated: false, isAuthenticated: false,
@ -73,10 +73,12 @@ const authReducer = (state = initialState, action) => {
localStorage.getItem(LANGUAGE) !== action.user.cultureName && localStorage.getItem(LANGUAGE) !== action.user.cultureName &&
localStorage.setItem(LANGUAGE, action.user.cultureName); localStorage.setItem(LANGUAGE, action.user.cultureName);
return Object.assign({}, state, { return Object.assign({}, state, {
isAuthenticated:
!isEmpty(action.user) || localStorage.getItem(AUTH_KEY),
user: action.user, user: action.user,
}); });
case SET_IS_AUTHENTICATED:
return Object.assign({}, state, {
isAuthenticated: action.isAuthenticated,
});
case SET_MODULES: case SET_MODULES:
return Object.assign({}, state, { return Object.assign({}, state, {
modules: action.modules, modules: action.modules,
@ -150,6 +152,7 @@ const authReducer = (state = initialState, action) => {
}); });
case LOGOUT: case LOGOUT:
return Object.assign({}, initialState, { return Object.assign({}, initialState, {
isLoaded: true,
settings: state.settings, settings: state.settings,
}); });
case SET_WIZARD_COMPLETED: case SET_WIZARD_COMPLETED:

View File

@ -45,6 +45,8 @@ const getCustomModules = (isAdmin) => {
export const getCurrentUser = (state) => state.auth.user; export const getCurrentUser = (state) => state.auth.user;
export const isAuthenticated = (state) => state.auth.isAuthenticated;
export const getCurrentUserId = (state) => state.auth.user; export const getCurrentUserId = (state) => state.auth.user;
export const getModules = (state) => state.auth.modules; export const getModules = (state) => state.auth.modules;

View File

@ -1,4 +1,4 @@
import { AUTH_KEY, LANGUAGE } from "../constants"; import { LANGUAGE } from "../constants";
import sjcl from "sjcl"; import sjcl from "sjcl";
import { isMobile } from "react-device-detect"; import { isMobile } from "react-device-detect";
@ -44,20 +44,6 @@ export function changeLanguage(
: i18n.changeLanguage("en"); : i18n.changeLanguage("en");
} }
export function redirectToDefaultPage() {
if (
(window.location.pathname === "/" ||
window.location.pathname === "" ||
window.location.pathname === "/login") &&
localStorage.getItem(AUTH_KEY) !== null
) {
setTimeout(() => window.location.replace("/products/files"), 0);
return true;
}
return false;
}
export function createPasswordHash(password, hashSettings) { export function createPasswordHash(password, hashSettings) {
if ( if (
!password || !password ||
@ -82,11 +68,21 @@ export function createPasswordHash(password, hashSettings) {
return hash; return hash;
} }
export function removeTempContent() { export function updateTempContent(isAuth = false) {
if (isAuth) {
let el = document.getElementById("burger-loader-svg");
let el1 = document.getElementById("logo-loader-svg");
let el2 = document.getElementById("avatar-loader-svg");
el.style.display = "block";
el1.style.display = "block";
el2.style.display = "block";
} else {
const tempElm = document.getElementById("temp-content"); const tempElm = document.getElementById("temp-content");
if (tempElm) { if (tempElm) {
tempElm.outerHTML = ""; tempElm.outerHTML = "";
} }
}
} }
export function hideLoader() { export function hideLoader() {
@ -109,3 +105,16 @@ export function showLoader() {
} }
export { withLayoutSize } from "./withLayoutSize"; export { withLayoutSize } from "./withLayoutSize";
export function tryRedirectTo(page) {
if (
window.location &&
window.location.pathname &&
window.location.pathname.indexOf(page) !== -1
)
return false;
//TODO: check if we already on default page
window.location.replace(page);
return true;
}

View File

@ -1,6 +1,6 @@
{ {
"name": "asc-web-components", "name": "asc-web-components",
"version": "1.0.489", "version": "1.0.490",
"description": "Ascensio System SIA component library", "description": "Ascensio System SIA component library",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "dist/asc-web-components.js", "main": "dist/asc-web-components.js",

View File

@ -5,7 +5,7 @@ import { Icons } from "../icons";
import Link from "../link"; import Link from "../link";
const whiteColor = "#FFFFFF"; const whiteColor = "#FFFFFF";
const avatarBackground = "#ECEEF1"; const avatarBackground = "#D0D5DA";
const namedAvatarBackground = "#2DA7DB"; const namedAvatarBackground = "#2DA7DB";
const noneUserSelect = css` const noneUserSelect = css`

View File

@ -5,8 +5,7 @@ import commonInputStyle from "../text-input/common-input-styles";
import MaskedInput from "react-text-mask"; import MaskedInput from "react-text-mask";
import isEqual from "lodash/isEqual"; import isEqual from "lodash/isEqual";
/* eslint-disable no-unused-vars */ /* eslint-disable no-unused-vars, react/prop-types */
/* eslint-disable react/prop-types */
const Input = ({ const Input = ({
isAutoFocussed, isAutoFocussed,
isDisabled, isDisabled,
@ -25,8 +24,7 @@ const Input = ({
) : ( ) : (
<input {...props} /> <input {...props} />
); );
/* eslint-enable react/prop-types */ /* eslint-enable react/prop-types, no-unused-vars */
/* eslint-enable no-unused-vars */
const StyledInput = styled(Input).attrs((props) => ({ const StyledInput = styled(Input).attrs((props) => ({
id: props.id, id: props.id,
@ -77,25 +75,31 @@ const StyledInput = styled(Input).attrs((props) => ({
transition: all 0.2s ease 0s; transition: all 0.2s ease 0s;
::-webkit-input-placeholder { ::-webkit-input-placeholder {
color: ${(props) => (props.isDisabled ? "#A3A9AE" : "#D0D5DA")}; color: "#A3A9AE";
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
user-select: none; user-select: none;
} }
:-moz-placeholder { :-moz-placeholder {
color: ${(props) => (props.isDisabled ? "#A3A9AE" : "#D0D5DA")}; color: "#A3A9AE";
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
user-select: none; user-select: none;
} }
::-moz-placeholder { ::-moz-placeholder {
color: ${(props) => (props.isDisabled ? "#A3A9AE" : "#D0D5DA")}; color: "#A3A9AE";
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
user-select: none; user-select: none;
} }
:-ms-input-placeholder { :-ms-input-placeholder {
color: ${(props) => (props.isDisabled ? "#A3A9AE" : "#D0D5DA")}; color: "#A3A9AE";
font-family: "Open Sans", sans-serif;
user-select: none;
}
::placeholder {
color: "#A3A9AE";
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
user-select: none; user-select: none;
} }

View File

@ -56,25 +56,31 @@ const StyledTextarea = styled(ClearTextareaAutosize)`
} }
::-webkit-input-placeholder { ::-webkit-input-placeholder {
color: ${(props) => (props.isDisabled ? "#D0D5DA" : "#D0D5DA")}; color: "#A3A9AE";
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
user-select: none; user-select: none;
} }
:-moz-placeholder { :-moz-placeholder {
color: ${(props) => (props.isDisabled ? "#D0D5DA" : "#D0D5DA")}; color: "#A3A9AE";
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
user-select: none; user-select: none;
} }
::-moz-placeholder { ::-moz-placeholder {
color: ${(props) => (props.isDisabled ? "#D0D5DA" : "#D0D5DA")}; color: "#A3A9AE";
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
user-select: none; user-select: none;
} }
:-ms-input-placeholder { :-ms-input-placeholder {
color: ${(props) => (props.isDisabled ? "#D0D5DA" : "#D0D5DA")}; color: "#A3A9AE";
font-family: "Open Sans", sans-serif;
user-select: none;
}
::placeholder {
color: "#A3A9AE";
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
user-select: none; user-select: none;
} }