|
@@ -7,6 +7,7 @@ import {
|
|
|
IDataWithMeta, IPageInfoForEntity, IPagePopulatedToShowRevision, isClient, isIPageInfoForEntity, isServer, IUser, IUserHasId, pagePathUtils, pathUtils,
|
|
IDataWithMeta, IPageInfoForEntity, IPagePopulatedToShowRevision, isClient, isIPageInfoForEntity, isServer, IUser, IUserHasId, pagePathUtils, pathUtils,
|
|
|
} from '@growi/core';
|
|
} from '@growi/core';
|
|
|
import ExtensibleCustomError from 'extensible-custom-error';
|
|
import ExtensibleCustomError from 'extensible-custom-error';
|
|
|
|
|
+import mongoose from 'mongoose';
|
|
|
import {
|
|
import {
|
|
|
NextPage, GetServerSideProps, GetServerSidePropsContext,
|
|
NextPage, GetServerSideProps, GetServerSidePropsContext,
|
|
|
} from 'next';
|
|
} from 'next';
|
|
@@ -30,6 +31,7 @@ import { RendererConfig } from '~/interfaces/services/renderer';
|
|
|
import { ISidebarConfig } from '~/interfaces/sidebar-config';
|
|
import { ISidebarConfig } from '~/interfaces/sidebar-config';
|
|
|
import { IUserUISettings } from '~/interfaces/user-ui-settings';
|
|
import { IUserUISettings } from '~/interfaces/user-ui-settings';
|
|
|
import { PageModel, PageDocument } from '~/server/models/page';
|
|
import { PageModel, PageDocument } from '~/server/models/page';
|
|
|
|
|
+import { PageRedirectModel } from '~/server/models/page-redirect';
|
|
|
import UserUISettings from '~/server/models/user-ui-settings';
|
|
import UserUISettings from '~/server/models/user-ui-settings';
|
|
|
import Xss from '~/services/xss';
|
|
import Xss from '~/services/xss';
|
|
|
import { useSWRxCurrentPage, useSWRxPageInfo } from '~/stores/page';
|
|
import { useSWRxCurrentPage, useSWRxPageInfo } from '~/stores/page';
|
|
@@ -43,8 +45,10 @@ import loggerFactory from '~/utils/logger';
|
|
|
|
|
|
|
|
// import GrowiSubNavigation from '../client/js/components/Navbar/GrowiSubNavigation';
|
|
// import GrowiSubNavigation from '../client/js/components/Navbar/GrowiSubNavigation';
|
|
|
// import GrowiSubNavigationSwitcher from '../client/js/components/Navbar/GrowiSubNavigationSwitcher';
|
|
// import GrowiSubNavigationSwitcher from '../client/js/components/Navbar/GrowiSubNavigationSwitcher';
|
|
|
|
|
+import ForbiddenPage from '../components/ForbiddenPage';
|
|
|
import { BasicLayout } from '../components/Layout/BasicLayout';
|
|
import { BasicLayout } from '../components/Layout/BasicLayout';
|
|
|
import GrowiContextualSubNavigation from '../components/Navbar/GrowiContextualSubNavigation';
|
|
import GrowiContextualSubNavigation from '../components/Navbar/GrowiContextualSubNavigation';
|
|
|
|
|
+import { NotCreatablePage } from '../components/NotCreatablePage';
|
|
|
import DisplaySwitcher from '../components/Page/DisplaySwitcher';
|
|
import DisplaySwitcher from '../components/Page/DisplaySwitcher';
|
|
|
|
|
|
|
|
// import { serializeUserSecurely } from '../server/models/serializers/user-serializer';
|
|
// import { serializeUserSecurely } from '../server/models/serializers/user-serializer';
|
|
@@ -68,7 +72,6 @@ import { useXss } from '../stores/xss';
|
|
|
import {
|
|
import {
|
|
|
CommonProps, getNextI18NextConfig, getServerSideCommonProps, useCustomTitle,
|
|
CommonProps, getNextI18NextConfig, getServerSideCommonProps, useCustomTitle,
|
|
|
} from './utils/commons';
|
|
} from './utils/commons';
|
|
|
-import { registerTransformerForObjectId } from './utils/objectid-transformer';
|
|
|
|
|
// import { useCurrentPageSWR } from '../stores/page';
|
|
// import { useCurrentPageSWR } from '../stores/page';
|
|
|
|
|
|
|
|
|
|
|
|
@@ -83,9 +86,6 @@ const { removeHeadingSlash } = pathUtils;
|
|
|
type IPageToShowRevisionWithMeta = IDataWithMeta<IPagePopulatedToShowRevision & PageDocument, IPageInfoForEntity>;
|
|
type IPageToShowRevisionWithMeta = IDataWithMeta<IPagePopulatedToShowRevision & PageDocument, IPageInfoForEntity>;
|
|
|
type IPageToShowRevisionWithMetaSerialized = IDataWithMeta<string, string>;
|
|
type IPageToShowRevisionWithMetaSerialized = IDataWithMeta<string, string>;
|
|
|
|
|
|
|
|
-// register custom serializer
|
|
|
|
|
-registerTransformerForObjectId();
|
|
|
|
|
-
|
|
|
|
|
superjson.registerCustom<IPageToShowRevisionWithMeta, IPageToShowRevisionWithMetaSerialized>(
|
|
superjson.registerCustom<IPageToShowRevisionWithMeta, IPageToShowRevisionWithMetaSerialized>(
|
|
|
{
|
|
{
|
|
|
isApplicable: (v): v is IPageToShowRevisionWithMeta => {
|
|
isApplicable: (v): v is IPageToShowRevisionWithMeta => {
|
|
@@ -126,8 +126,7 @@ type Props = CommonProps & {
|
|
|
|
|
|
|
|
pageWithMeta: IPageToShowRevisionWithMeta,
|
|
pageWithMeta: IPageToShowRevisionWithMeta,
|
|
|
// pageUser?: any,
|
|
// pageUser?: any,
|
|
|
- // redirectTo?: string;
|
|
|
|
|
- // redirectFrom?: string;
|
|
|
|
|
|
|
+ redirectFrom?: string;
|
|
|
|
|
|
|
|
// shareLinkId?: string;
|
|
// shareLinkId?: string;
|
|
|
isLatestRevision?: boolean
|
|
isLatestRevision?: boolean
|
|
@@ -305,10 +304,10 @@ const GrowiPage: NextPage<Props> = (props: Props) => {
|
|
|
{ !props.isIdenticalPathPage && (
|
|
{ !props.isIdenticalPathPage && (
|
|
|
<>
|
|
<>
|
|
|
<PageAlerts />
|
|
<PageAlerts />
|
|
|
- { props.isForbidden
|
|
|
|
|
- ? <>ForbiddenPage</>
|
|
|
|
|
- : <DisplaySwitcher />
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ { props.isForbidden && <ForbiddenPage /> }
|
|
|
|
|
+ { props.IsNotCreatable && <NotCreatablePage />}
|
|
|
|
|
+ { !props.isForbidden && !props.IsNotCreatable && <DisplaySwitcher />}
|
|
|
|
|
+ {/* <DisplaySwitcher /> */}
|
|
|
<div id="page-editor-navbar-bottom-container" className="d-none d-edit-block"></div>
|
|
<div id="page-editor-navbar-bottom-container" className="d-none d-edit-block"></div>
|
|
|
{/* <PageStatusAlert /> */}
|
|
{/* <PageStatusAlert /> */}
|
|
|
PageStatusAlert
|
|
PageStatusAlert
|
|
@@ -360,17 +359,28 @@ async function injectPageData(context: GetServerSidePropsContext, props: Props):
|
|
|
const { revisionId } = req.query;
|
|
const { revisionId } = req.query;
|
|
|
|
|
|
|
|
const Page = crowi.model('Page') as PageModel;
|
|
const Page = crowi.model('Page') as PageModel;
|
|
|
|
|
+ const PageRedirect = mongoose.model('PageRedirect') as PageRedirectModel;
|
|
|
const { pageService } = crowi;
|
|
const { pageService } = crowi;
|
|
|
|
|
|
|
|
- const { currentPathname } = props;
|
|
|
|
|
|
|
+ let currentPathname = props.currentPathname;
|
|
|
|
|
|
|
|
const pageId = getPageIdFromPathname(currentPathname);
|
|
const pageId = getPageIdFromPathname(currentPathname);
|
|
|
const isPermalink = _isPermalink(currentPathname);
|
|
const isPermalink = _isPermalink(currentPathname);
|
|
|
|
|
|
|
|
const { user } = req;
|
|
const { user } = req;
|
|
|
|
|
|
|
|
- // check whether the specified page path hits to multiple pages
|
|
|
|
|
if (!isPermalink) {
|
|
if (!isPermalink) {
|
|
|
|
|
+ // check redirects
|
|
|
|
|
+ const chains = await PageRedirect.retrievePageRedirectEndpoints(currentPathname);
|
|
|
|
|
+ if (chains != null) {
|
|
|
|
|
+ // overwrite currentPathname
|
|
|
|
|
+ currentPathname = chains.end.toPath;
|
|
|
|
|
+ props.currentPathname = currentPathname;
|
|
|
|
|
+ // set redirectFrom
|
|
|
|
|
+ props.redirectFrom = chains.start.fromPath;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // check whether the specified page path hits to multiple pages
|
|
|
const count = await Page.countByPathAndViewer(currentPathname, user, null, true);
|
|
const count = await Page.countByPathAndViewer(currentPathname, user, null, true);
|
|
|
if (count > 1) {
|
|
if (count > 1) {
|
|
|
throw new MultiplePagesHitsError(currentPathname);
|
|
throw new MultiplePagesHitsError(currentPathname);
|
|
@@ -416,9 +426,7 @@ async function injectRoutingInformation(context: GetServerSidePropsContext, prop
|
|
|
}
|
|
}
|
|
|
else if (page == null) {
|
|
else if (page == null) {
|
|
|
props.isNotFound = true;
|
|
props.isNotFound = true;
|
|
|
-
|
|
|
|
|
props.IsNotCreatable = !isCreatablePage(currentPathname);
|
|
props.IsNotCreatable = !isCreatablePage(currentPathname);
|
|
|
-
|
|
|
|
|
// check the page is forbidden or just does not exist.
|
|
// check the page is forbidden or just does not exist.
|
|
|
const count = isPermalink ? await Page.count({ _id: pageId }) : await Page.count({ path: currentPathname });
|
|
const count = isPermalink ? await Page.count({ _id: pageId }) : await Page.count({ path: currentPathname });
|
|
|
props.isForbidden = count > 0;
|
|
props.isForbidden = count > 0;
|