Merge pull request #270 from ONLYOFFICE/feature/rewrite-routes

Feature/rewrite routes
This commit is contained in:
Alexey Safronov 2024-02-22 16:25:43 +04:00 committed by GitHub
commit c3d40484b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 331 additions and 196 deletions

View File

@ -0,0 +1,87 @@
import { inject, observer } from "mobx-react";
import { PrivateRoute } from "@docspace/shared/routes";
import type { PrivateRouteProps } from "@docspace/shared/routes";
const PrivateRouteWrapper = ({
wizardCompleted,
children,
enablePortalRename,
isAdmin,
isAuthenticated,
isCommunity,
isEnterprise,
isLoaded,
isLogout,
isNotPaidPeriod,
isPortalDeactivate,
limitedAccessSpace,
tenantStatus,
user,
restricted,
withCollaborator,
withManager,
}: Partial<PrivateRouteProps>) => {
return (
<PrivateRoute
user={user!}
isAdmin={isAdmin!}
isLoaded={isLoaded!}
isLogout={isLogout!}
restricted={restricted}
withManager={withManager}
isCommunity={isCommunity}
isEnterprise={isEnterprise}
tenantStatus={tenantStatus!}
isAuthenticated={isAuthenticated}
wizardCompleted={wizardCompleted!}
isNotPaidPeriod={isNotPaidPeriod!}
withCollaborator={withCollaborator}
isPortalDeactivate={isPortalDeactivate!}
enablePortalRename={enablePortalRename!}
limitedAccessSpace={limitedAccessSpace!}
>
{children}
</PrivateRoute>
);
};
export default inject<TStore>(
({ authStore, settingsStore, userStore, currentTariffStatusStore }) => {
const {
isAuthenticated,
isLoaded,
isAdmin,
isLogout,
isCommunity,
isEnterprise,
} = authStore;
const { isNotPaidPeriod } = currentTariffStatusStore;
const { user } = userStore;
const {
wizardCompleted,
tenantStatus,
isPortalDeactivate,
enablePortalRename,
limitedAccessSpace,
} = settingsStore;
return {
isPortalDeactivate,
isCommunity,
isNotPaidPeriod,
user,
isAuthenticated,
isAdmin,
isLoaded,
wizardCompleted,
tenantStatus,
isLogout,
isEnterprise,
enablePortalRename,
limitedAccessSpace,
};
},
)(observer(PrivateRouteWrapper));

View File

@ -0,0 +1,35 @@
import { inject, observer } from "mobx-react";
import { PublicRoute } from "@docspace/shared/routes";
import type { PublicRouteProps } from "@docspace/shared/routes";
const PublicRouteWrapper = ({
children,
isAuthenticated,
isPortalDeactivate,
tenantStatus,
wizardCompleted,
}: Partial<PublicRouteProps>) => {
return (
<PublicRoute
tenantStatus={tenantStatus!}
isAuthenticated={isAuthenticated}
wizardCompleted={wizardCompleted!}
isPortalDeactivate={isPortalDeactivate!}
>
{children}
</PublicRoute>
);
};
export default inject<TStore>(({ authStore, settingsStore }) => {
const { isAuthenticated } = authStore;
const { wizardCompleted, tenantStatus, isPortalDeactivate } = settingsStore;
return {
tenantStatus,
wizardCompleted,
isAuthenticated,
isPortalDeactivate,
};
})(observer(PublicRouteWrapper));

View File

@ -2,8 +2,8 @@ import React from "react";
import { Navigate } from "react-router-dom";
import loadable from "@loadable/component";
import PrivateRoute from "@docspace/common/components/PrivateRoute";
import PublicRoute from "@docspace/common/components/PublicRoute";
import PrivateRoute from "../components/PrivateRouteWrapper";
import PublicRoute from "../components/PublicRouteWrapper";
import Error404 from "@docspace/shared/components/errors/Error404";
import ErrorBoundary from "../components/ErrorBoundaryWrapper";

View File

@ -3,7 +3,7 @@ import { Navigate } from "react-router-dom";
import loadable from "@loadable/component";
import PrivateRoute from "@docspace/common/components/PrivateRoute";
import PrivateRoute from "../components/PrivateRouteWrapper";
const Profile = loadable(() => import("../pages/Profile"));

View File

@ -2,7 +2,7 @@ import React from "react";
import { Navigate } from "react-router-dom";
import loadable from "@loadable/component";
import PrivateRoute from "@docspace/common/components/PrivateRoute";
import PrivateRoute from "../components/PrivateRouteWrapper";
import ErrorBoundary from "../components/ErrorBoundaryWrapper";
import Error404 from "@docspace/shared/components/errors/Error404";
@ -12,180 +12,202 @@ import { generalRoutes } from "./general";
const PortalSettings = loadable(() => import("../pages/PortalSettings"));
const CustomizationSettings = loadable(
() => import("../pages/PortalSettings/categories/common/index.js")
() => import("../pages/PortalSettings/categories/common/index.js"),
);
const LanguageAndTimeZoneSettings = loadable(
() =>
import(
"../pages/PortalSettings/categories/common/Customization/language-and-time-zone"
)
import(
"../pages/PortalSettings/categories/common/Customization/language-and-time-zone"
),
);
const WelcomePageSettings = loadable(
() =>
import(
"../pages/PortalSettings/categories/common/Customization/welcome-page-settings"
)
import(
"../pages/PortalSettings/categories/common/Customization/welcome-page-settings"
),
);
const DNSSettings = loadable(
() =>
import(
"../pages/PortalSettings/categories/common/Customization/dns-settings"
)
),
);
const PortalRenaming = loadable(
() =>
import(
"../pages/PortalSettings/categories/common/Customization/portal-renaming"
)
import(
"../pages/PortalSettings/categories/common/Customization/portal-renaming"
),
);
const WhiteLabel = loadable(
() => import("../pages/PortalSettings/categories/common/Branding/whitelabel")
() => import("../pages/PortalSettings/categories/common/Branding/whitelabel"),
);
const CompanyInfoSettings = loadable(
() =>
import(
"../pages/PortalSettings/categories/common/Branding/companyInfoSettings"
)
import(
"../pages/PortalSettings/categories/common/Branding/companyInfoSettings"
),
);
const AdditionalResources = loadable(
() =>
import(
"../pages/PortalSettings/categories/common/Branding/additionalResources"
)
import(
"../pages/PortalSettings/categories/common/Branding/additionalResources"
),
);
const SecuritySettings = loadable(
() => import("../pages/PortalSettings/categories/security/index.js")
() => import("../pages/PortalSettings/categories/security/index.js"),
);
const TfaPage = loadable(
() => import("../pages/PortalSettings/categories/security/access-portal/tfa")
() => import("../pages/PortalSettings/categories/security/access-portal/tfa"),
);
const PasswordStrengthPage = loadable(
() =>
import(
"../pages/PortalSettings/categories/security/access-portal/passwordStrength"
)
import(
"../pages/PortalSettings/categories/security/access-portal/passwordStrength"
),
);
const TrustedMailPage = loadable(
() =>
import(
"../pages/PortalSettings/categories/security/access-portal/trustedMail"
)
import(
"../pages/PortalSettings/categories/security/access-portal/trustedMail"
),
);
const IpSecurityPage = loadable(
() =>
import(
"../pages/PortalSettings/categories/security/access-portal/ipSecurity"
)
),
);
const BruteForceProtectionPage = loadable(
() =>
import(
"../pages/PortalSettings/categories/security/access-portal/bruteForceProtection"
)
import(
"../pages/PortalSettings/categories/security/access-portal/bruteForceProtection"
),
);
const AdminMessagePage = loadable(
() =>
import(
"../pages/PortalSettings/categories/security/access-portal/adminMessage"
)
import(
"../pages/PortalSettings/categories/security/access-portal/adminMessage"
),
);
const SessionLifetimePage = loadable(
() =>
import(
"../pages/PortalSettings/categories/security/access-portal/sessionLifetime"
)
import(
"../pages/PortalSettings/categories/security/access-portal/sessionLifetime"
),
);
const Integration = loadable(
() => import("../pages/PortalSettings/categories/integration")
() => import("../pages/PortalSettings/categories/integration"),
);
const Payments = loadable(
() => import("../pages/PortalSettings/categories/payments")
() => import("../pages/PortalSettings/categories/payments"),
);
const Statistics = loadable(() =>
import("../pages/PortalSettings/categories/storage-management")
const Statistics = loadable(
() => import("../pages/PortalSettings/categories/storage-management"),
);
const QuotaPerRoom = loadable(() =>
import(
"../pages/PortalSettings/categories/storage-management/sub-components/QuotaPerRoom.js"
)
const QuotaPerRoom = loadable(
() =>
import(
"../pages/PortalSettings/categories/storage-management/sub-components/QuotaPerRoom.js"
),
);
const QuotaPerUser = loadable(() =>
import(
"../pages/PortalSettings/categories/storage-management/sub-components/QuotaPerUser.js"
)
const QuotaPerUser = loadable(
() =>
import(
"../pages/PortalSettings/categories/storage-management/sub-components/QuotaPerUser.js"
),
);
const ThirdParty = loadable(() =>
import(
"../pages/PortalSettings/categories/integration/ThirdPartyServicesSettings"
)
const ThirdParty = loadable(
() =>
import(
"../pages/PortalSettings/categories/integration/ThirdPartyServicesSettings"
),
);
const DocumentService = loadable(
() => import("../pages/PortalSettings/categories/integration/DocumentService")
() =>
import("../pages/PortalSettings/categories/integration/DocumentService"),
);
const SingleSignOn = loadable(
() => import("../pages/PortalSettings/categories/integration/SingleSignOn")
() => import("../pages/PortalSettings/categories/integration/SingleSignOn"),
);
const SPSettings = loadable(
() =>
import(
"../pages/PortalSettings/categories/integration/SingleSignOn/SPSettings"
)
import(
"../pages/PortalSettings/categories/integration/SingleSignOn/SPSettings"
),
);
const SPMetadata = loadable(
() =>
import(
"../pages/PortalSettings/categories/integration/SingleSignOn/ProviderMetadata"
)
import(
"../pages/PortalSettings/categories/integration/SingleSignOn/ProviderMetadata"
),
);
const DeveloperTools = loadable(
() => import("../pages/PortalSettings/categories/developer-tools/index.js")
() => import("../pages/PortalSettings/categories/developer-tools/index.js"),
);
const WebhookHistory = loadable(
() =>
import(
"../pages/PortalSettings/categories/developer-tools/Webhooks/WebhookHistory"
)
import(
"../pages/PortalSettings/categories/developer-tools/Webhooks/WebhookHistory"
),
);
const WebhookDetails = loadable(
() =>
import(
"../pages/PortalSettings/categories/developer-tools/Webhooks/WebhookEventDetails"
)
import(
"../pages/PortalSettings/categories/developer-tools/Webhooks/WebhookEventDetails"
),
);
const Backup = loadable(
() => import("../pages/PortalSettings/categories/data-management/index")
() => import("../pages/PortalSettings/categories/data-management/index"),
);
const DeleteDataPage = loadable(
() => import("../pages/PortalSettings/categories/delete-data")
() => import("../pages/PortalSettings/categories/delete-data"),
);
const RestoreBackup = loadable(
() =>
import(
"../pages/PortalSettings/categories/data-management/backup/restore-backup/index"
)
import(
"../pages/PortalSettings/categories/data-management/backup/restore-backup/index"
),
);
const Bonus = loadable(() => import("../pages/Bonus"));
const SimpleRoom = loadable(() =>
import("../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/SimpleRoom")
const SimpleRoom = loadable(
() =>
import(
"../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/SimpleRoom"
),
);
const Manager = loadable(() =>
import("../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Manager")
const Manager = loadable(
() =>
import(
"../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Manager"
),
);
const RoomSelector = loadable(() =>
import("../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/RoomSelector")
const RoomSelector = loadable(
() =>
import(
"../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/RoomSelector"
),
);
const FileSelector = loadable(() =>
import("../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/FileSelector")
const FileSelector = loadable(
() =>
import(
"../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/FileSelector"
),
);
const Editor = loadable(() =>
import("../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Editor")
const Editor = loadable(
() =>
import(
"../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Editor"
),
);
const Viewer = loadable(() =>
import("../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Viewer")
const Viewer = loadable(
() =>
import(
"../pages/PortalSettings/categories/developer-tools/JavascriptSDK/presets/Viewer"
),
);
const PortalSettingsRoutes = {

View File

@ -1,4 +1,3 @@
export { default as PrivateRoute } from "./PrivateRoute";
export { default as PublicRoute } from "./PublicRoute";
export { default as ExternalRedirect } from "./ExternalRedirect";
export { default as AdvancedSelector } from "./AdvancedSelector";

View File

@ -1,37 +1,37 @@
/* eslint-disable react/prop-types */
import React from "react";
import { Navigate, useLocation } from "react-router-dom";
import { inject, observer } from "mobx-react";
import Error403 from "@docspace/shared/components/errors/Error403";
import Error403 from "@docspace/shared/components/errors/Error403";
import AppLoader from "@docspace/shared/components/app-loader";
import { combineUrl } from "@docspace/shared/utils/combineUrl";
import { TenantStatus } from "@docspace/shared/enums";
import { combineUrl } from "@docspace/shared/utils/combineUrl";
const PrivateRoute = ({ children, ...rest }) => {
import type { PrivateRouteProps } from "./Routers.types";
export const PrivateRoute = (props: PrivateRouteProps) => {
const {
isAdmin,
isAuthenticated,
isLoaded,
restricted,
user,
wizardCompleted,
tenantStatus,
isNotPaidPeriod,
withManager,
withCollaborator,
isLogout,
standalone,
isCommunity,
isEnterprise,
isNotPaidPeriod,
isAuthenticated,
isPortalDeactivate,
enablePortalRename,
withManager,
withCollaborator,
wizardCompleted,
user,
children,
restricted,
tenantStatus,
limitedAccessSpace,
} = rest;
enablePortalRename,
} = props;
const location = useLocation();
@ -39,7 +39,7 @@ const PrivateRoute = ({ children, ...rest }) => {
if (!user && isAuthenticated) {
if (isPortalDeactivate) {
window.location.replace(
combineUrl(window.DocSpaceConfig?.proxy?.url, "/unavailable")
combineUrl(window.DocSpaceConfig?.proxy?.url, "/unavailable"),
);
return null;
@ -71,7 +71,7 @@ const PrivateRoute = ({ children, ...rest }) => {
if (isLoaded && !isAuthenticated) {
if (isPortalDeactivate) {
window.location.replace(
combineUrl(window.DocSpaceConfig?.proxy?.url, "/unavailable")
combineUrl(window.DocSpaceConfig?.proxy?.url, "/unavailable"),
);
return null;
@ -88,7 +88,7 @@ const PrivateRoute = ({ children, ...rest }) => {
}
window.location.replace(
combineUrl(window.DocSpaceConfig?.proxy?.url, redirectPath)
combineUrl(window.DocSpaceConfig?.proxy?.url, redirectPath),
);
return null;
@ -97,11 +97,11 @@ const PrivateRoute = ({ children, ...rest }) => {
if (
isLoaded &&
((!isNotPaidPeriod && isPortalUnavailableUrl) ||
(!user.isOwner && isPortalDeletionUrl) ||
(!user?.isOwner && isPortalDeletionUrl) ||
(isCommunity && isPaymentsUrl) ||
(isEnterprise && isBonusPage))
) {
return <Navigate replace to={"/"} />;
return <Navigate replace to="/" />;
}
if (isLoaded && limitedAccessSpace && isPortalDeletionUrl) {
@ -119,7 +119,7 @@ const PrivateRoute = ({ children, ...rest }) => {
replace
to={combineUrl(
window.DocSpaceConfig?.proxy?.url,
"/preparation-portal"
"/preparation-portal",
)}
/>
);
@ -128,7 +128,7 @@ const PrivateRoute = ({ children, ...rest }) => {
if (
isNotPaidPeriod &&
isLoaded &&
(user.isOwner || user.isAdmin) &&
(user?.isOwner || user?.isAdmin) &&
!isPaymentsUrl &&
!isBackupUrl &&
!isPortalDeletionUrl
@ -138,7 +138,7 @@ const PrivateRoute = ({ children, ...rest }) => {
replace
to={combineUrl(
window.DocSpaceConfig?.proxy?.url,
"/portal-settings/payments/portal-payments"
"/portal-settings/payments/portal-payments",
)}
/>
);
@ -147,8 +147,8 @@ const PrivateRoute = ({ children, ...rest }) => {
if (
isNotPaidPeriod &&
isLoaded &&
!user.isOwner &&
!user.isAdmin &&
!user?.isOwner &&
!user?.isAdmin &&
!isPortalUnavailableUrl
) {
return (
@ -156,7 +156,7 @@ const PrivateRoute = ({ children, ...rest }) => {
replace
to={combineUrl(
window.DocSpaceConfig?.proxy?.url,
"/portal-unavailable"
"/portal-unavailable",
)}
/>
);
@ -195,72 +195,26 @@ const PrivateRoute = ({ children, ...rest }) => {
// }
if (isPortalRenameUrl && !enablePortalRename) {
return <Navigate replace to={"/error/404"} />;
return <Navigate replace to="/error/404" />;
}
if (
!restricted ||
isAdmin ||
(withManager && !user.isVisitor && !user.isCollaborator) ||
(withCollaborator && !user.isVisitor)
(withManager && !user?.isVisitor && !user?.isCollaborator) ||
(withCollaborator && !user?.isVisitor)
) {
return children;
}
if (restricted) {
return <Navigate replace to={"/error/401"} />;
return <Navigate replace to="/error/401" />;
}
return <Navigate replace to={"/error/404"} />;
return <Navigate replace to="/error/404" />;
};
const component = renderComponent();
return component;
};
export default inject(
({ authStore, settingsStore, userStore, currentTariffStatusStore }) => {
const {
isAuthenticated,
isLoaded,
isAdmin,
isLogout,
isCommunity,
isEnterprise,
} = authStore;
const { isNotPaidPeriod } = currentTariffStatusStore;
const { user } = userStore;
const {
setModuleInfo,
wizardCompleted,
personal,
tenantStatus,
standalone,
isPortalDeactivate,
enablePortalRename,
limitedAccessSpace,
} = settingsStore;
return {
isPortalDeactivate,
isCommunity,
isNotPaidPeriod,
user,
isAuthenticated,
isAdmin,
isLoaded,
wizardCompleted,
tenantStatus,
isLogout,
standalone,
isEnterprise,
enablePortalRename,
limitedAccessSpace,
};
}
)(observer(PrivateRoute));

View File

@ -1,14 +1,20 @@
/* eslint-disable react/prop-types */
import React from "react";
import { Navigate, Route, useLocation } from "react-router-dom";
//import AppLoader from "../AppLoader";
import { combineUrl } from "@docspace/shared/utils/combineUrl";
import { inject, observer } from "mobx-react";
import { TenantStatus } from "@docspace/shared/enums";
import { Navigate, useLocation } from "react-router-dom";
export const PublicRoute = ({ children, ...rest }) => {
const { wizardCompleted, isAuthenticated, tenantStatus, isPortalDeactivate } =
rest;
import { TenantStatus } from "@docspace/shared/enums";
import { combineUrl } from "@docspace/shared/utils/combineUrl";
import type { PublicRouteProps } from "./Routers.types";
export const PublicRoute = (props: PublicRouteProps) => {
const {
wizardCompleted,
isAuthenticated,
tenantStatus,
isPortalDeactivate,
children,
} = props;
const location = useLocation();
@ -34,7 +40,7 @@ export const PublicRoute = ({ children, ...rest }) => {
(isAuthenticated && !isPortalRestoring && !isPortalDeactivate) ||
(!location?.state?.isRestrictionError && isPortalRestriction)
) {
return <Navigate replace to={"/"} />;
return <Navigate replace to="/" />;
}
if (isAuthenticated && isPortalRestoring && !isPreparationPortalUrl) {
@ -43,7 +49,7 @@ export const PublicRoute = ({ children, ...rest }) => {
replace
to={combineUrl(
window.DocSpaceConfig?.proxy?.url,
"/preparation-portal"
"/preparation-portal",
)}
/>
);
@ -57,7 +63,7 @@ export const PublicRoute = ({ children, ...rest }) => {
);
}
if (!wizardCompleted && location.pathname !== "/wizard") {
return <Navigate replace to={"/wizard"} />;
return <Navigate replace to="/wizard" />;
}
if (
@ -71,7 +77,7 @@ export const PublicRoute = ({ children, ...rest }) => {
replace
to={combineUrl(
window.DocSpaceConfig?.proxy?.url,
"/preparation-portal"
"/preparation-portal",
)}
/>
);
@ -97,7 +103,7 @@ export const PublicRoute = ({ children, ...rest }) => {
!isPortalDeactivate
) {
window.location.replace(
combineUrl(window.DocSpaceConfig?.proxy?.url, "/login")
combineUrl(window.DocSpaceConfig?.proxy?.url, "/login"),
);
return null;
@ -110,16 +116,3 @@ export const PublicRoute = ({ children, ...rest }) => {
return component;
};
export default inject(({ authStore, settingsStore }) => {
const { isAuthenticated, isLoaded } = authStore;
const { wizardCompleted, tenantStatus, isPortalDeactivate } = settingsStore;
return {
tenantStatus,
wizardCompleted,
isAuthenticated,
isLoaded,
isPortalDeactivate,
};
})(observer(PublicRoute));

View File

@ -0,0 +1,40 @@
import type { PropsWithChildren } from "react";
import type { AuthStore } from "../store/AuthStore";
import type { UserStore } from "../store/UserStore";
import type { SettingsStore } from "../store/SettingsStore";
import type { CurrentTariffStatusStore } from "../store/CurrentTariffStatusStore";
export interface PrivateRouteProps
extends PropsWithChildren,
Pick<
AuthStore,
| "isAuthenticated"
| "isLoaded"
| "isAdmin"
| "isLogout"
| "isCommunity"
| "isEnterprise"
>,
Pick<
SettingsStore,
| "wizardCompleted"
| "tenantStatus"
| "isPortalDeactivate"
| "enablePortalRename"
| "limitedAccessSpace"
>,
Pick<CurrentTariffStatusStore, "isNotPaidPeriod">,
Pick<UserStore, "user"> {
restricted?: boolean;
withManager?: boolean;
withCollaborator?: boolean;
}
export interface PublicRouteProps
extends PropsWithChildren,
Pick<AuthStore, "isAuthenticated">,
Pick<
SettingsStore,
"wizardCompleted" | "tenantStatus" | "isPortalDeactivate"
> {}

View File

@ -0,0 +1,4 @@
export { PrivateRoute } from "./Route.private";
export { PublicRoute } from "./Route.public";
export type { PrivateRouteProps, PublicRouteProps } from "./Routers.types";

View File

@ -24,6 +24,7 @@
".storybook",
"babel.config.ts",
"index.d.ts",
"tsconfig.eslint.json"
"tsconfig.eslint.json",
"routes"
]
}