Procházet zdrojové kódy

refactor(get-page-by-share-link): streamline request handling and remove unused code

Shun Miyazawa před 6 dny
rodič
revize
c9a15a528d

+ 11 - 19
apps/app/src/server/routes/apiv3/page/get-page-by-share-link.ts

@@ -1,13 +1,9 @@
-import { SCOPE } from '@growi/core';
 import { ErrorV3 } from '@growi/core/dist/models';
 import { ErrorV3 } from '@growi/core/dist/models';
 import type { Request, RequestHandler } from 'express';
 import type { Request, RequestHandler } from 'express';
 import { query } from 'express-validator';
 import { query } from 'express-validator';
-import type { HydratedDocument } from 'mongoose';
-import mongoose from 'mongoose';
 
 
 import type Crowi from '~/server/crowi';
 import type Crowi from '~/server/crowi';
 import { apiV3FormValidator } from '~/server/middlewares/apiv3-form-validator';
 import { apiV3FormValidator } from '~/server/middlewares/apiv3-form-validator';
-import type { IPage, IPageModel } from '~/server/models/page';
 import ShareLink from '~/server/models/share-link';
 import ShareLink from '~/server/models/share-link';
 import { configManager } from '~/server/service/config-manager';
 import { configManager } from '~/server/service/config-manager';
 import { findPageAndMetaDataByViewer } from '~/server/service/page/find-page-and-meta-data-by-viewer';
 import { findPageAndMetaDataByViewer } from '~/server/service/page/find-page-and-meta-data-by-viewer';
@@ -19,10 +15,12 @@ import { respondWithSinglePage } from './respond-with-single-page';
 
 
 const logger = loggerFactory('growi:routes:apiv3:page:get-page-by-share-link');
 const logger = loggerFactory('growi:routes:apiv3:page:get-page-by-share-link');
 
 
-// Extend Request to include middleware-added properties
-interface RequestWithShareLink extends Request {
-  // No authentication properties expected for this public endpoint
-}
+type ReqQuery = {
+  pageId: string;
+  shareLinkId: string;
+};
+
+type Req = Request<Record<string, string>, ApiV3Response, undefined, ReqQuery>;
 
 
 /**
 /**
  * @swagger
  * @swagger
@@ -63,7 +61,6 @@ export const getPageByShareLinkHandlerFactory = (
   crowi: Crowi,
   crowi: Crowi,
 ): RequestHandler[] => {
 ): RequestHandler[] => {
   const { pageService, pageGrantService } = crowi;
   const { pageService, pageGrantService } = crowi;
-  const Page = mongoose.model<IPage, IPageModel>('Page');
 
 
   // Define validators for req.query - both parameters required
   // Define validators for req.query - both parameters required
   const validator = [
   const validator = [
@@ -74,13 +71,8 @@ export const getPageByShareLinkHandlerFactory = (
   return [
   return [
     ...validator,
     ...validator,
     apiV3FormValidator,
     apiV3FormValidator,
-    async (req: RequestWithShareLink, res: ApiV3Response) => {
-      const { shareLinkId, pageId } = req.query;
-
-      // Convert to strings (already validated as MongoId by express-validator)
-      const shareLinkIdString =
-        typeof shareLinkId === 'string' ? shareLinkId : String(shareLinkId);
-      const pageIdString = typeof pageId === 'string' ? pageId : String(pageId);
+    async (req: Req, res: ApiV3Response) => {
+      const { pageId, shareLinkId } = req.query;
 
 
       try {
       try {
         // First gate: Check if link sharing is enabled globally
         // First gate: Check if link sharing is enabled globally
@@ -97,8 +89,8 @@ export const getPageByShareLinkHandlerFactory = (
         // Validate ShareLink by ID and page ID in a single query
         // Validate ShareLink by ID and page ID in a single query
         const validationResult = await validateShareLink(
         const validationResult = await validateShareLink(
           ShareLink,
           ShareLink,
-          shareLinkIdString,
-          pageIdString,
+          shareLinkId,
+          pageId,
         );
         );
 
 
         if (validationResult.type === 'not-found') {
         if (validationResult.type === 'not-found') {
@@ -121,7 +113,7 @@ export const getPageByShareLinkHandlerFactory = (
           pageService,
           pageService,
           pageGrantService,
           pageGrantService,
           {
           {
-            pageId: pageIdString,
+            pageId,
             path: null,
             path: null,
             user: undefined,
             user: undefined,
             isSharedPage: true,
             isSharedPage: true,

+ 3 - 61
apps/app/src/server/routes/apiv3/page/index.ts

@@ -56,6 +56,7 @@ import { getPageInfoHandlerFactory } from './get-page-info';
 import { getPagePathsWithDescendantCountFactory } from './get-page-paths-with-descendant-count';
 import { getPagePathsWithDescendantCountFactory } from './get-page-paths-with-descendant-count';
 import { getYjsDataHandlerFactory } from './get-yjs-data';
 import { getYjsDataHandlerFactory } from './get-yjs-data';
 import { publishPageHandlersFactory } from './publish-page';
 import { publishPageHandlersFactory } from './publish-page';
+import { respondWithSinglePage } from './respond-with-single-page';
 import { syncLatestRevisionBodyToYjsDraftHandlerFactory } from './sync-latest-revision-body-to-yjs-draft';
 import { syncLatestRevisionBodyToYjsDraftHandlerFactory } from './sync-latest-revision-body-to-yjs-draft';
 import { unpublishPageHandlersFactory } from './unpublish-page';
 import { unpublishPageHandlersFactory } from './unpublish-page';
 import { updatePageHandlersFactory } from './update-page';
 import { updatePageHandlersFactory } from './update-page';
@@ -210,67 +211,6 @@ module.exports = (crowi: Crowi) => {
         'security:disableUserPages',
         'security:disableUserPages',
       );
       );
 
 
-      const respondWithSinglePage = async (
-        pageWithMeta:
-          | IDataWithMeta<HydratedDocument<PageDocument>, IPageInfoExt>
-          | IDataWithMeta<null, IPageNotFoundInfo>,
-      ) => {
-        let { data: page } = pageWithMeta;
-        const { meta } = pageWithMeta;
-
-        if (isIPageNotFoundInfo(meta)) {
-          if (meta.isForbidden) {
-            return res.apiv3Err(
-              new ErrorV3(
-                'Page is forbidden',
-                'page-is-forbidden',
-                undefined,
-                meta,
-              ),
-              403,
-            );
-          }
-          return res.apiv3Err(
-            new ErrorV3('Page is not found', 'page-not-found', undefined, meta),
-            404,
-          );
-        }
-
-        if (disableUserPages && page != null) {
-          const isTargetUserPage =
-            isUserPage(page.path) || isUsersTopPage(page.path);
-
-          if (isTargetUserPage) {
-            return res.apiv3Err(
-              new ErrorV3('Page is forbidden', 'page-is-forbidden'),
-              403,
-            );
-          }
-        }
-
-        if (page != null) {
-          try {
-            page.initLatestRevisionField(revisionId);
-
-            // populate
-            page = await page.populateDataToShowRevision();
-          } catch (err) {
-            logger.error('populate-page-failed', err);
-            return res.apiv3Err(
-              new ErrorV3(
-                'Failed to populate page',
-                'populate-page-failed',
-                undefined,
-                { err, meta },
-              ),
-              500,
-            );
-          }
-        }
-
-        return res.apiv3({ page, pages: undefined, meta });
-      };
-
       const isValid = pageId != null || path != null;
       const isValid = pageId != null || path != null;
       if (!isValid) {
       if (!isValid) {
         return res.apiv3Err(
         return res.apiv3Err(
@@ -299,11 +239,13 @@ module.exports = (crowi: Crowi) => {
         }
         }
 
 
         return respondWithSinglePage(
         return respondWithSinglePage(
+          res,
           await findPageAndMetaDataByViewer(pageService, pageGrantService, {
           await findPageAndMetaDataByViewer(pageService, pageGrantService, {
             pageId,
             pageId,
             path,
             path,
             user,
             user,
           }),
           }),
+          { revisionId, disableUserPages },
         );
         );
       } catch (err) {
       } catch (err) {
         logger.error('get-page-failed', err);
         logger.error('get-page-failed', err);