Pārlūkot izejas kodu

Merge branch 'feat/implement-resume-rename-operation' into feat/prevent-page-operation-from-being-processed-many-times-at-once

yohei0125 3 gadi atpakaļ
vecāks
revīzija
d3ba3df077

+ 13 - 0
packages/app/src/server/routes/apiv3/pages.js

@@ -551,6 +551,19 @@ module.exports = (crowi) => {
     return res.apiv3(result);
   });
 
+  router.put('/path-recovery-operation', accessTokenParser, loginRequiredStrictly, csrf, apiV3FormValidator, async(req, res) => {
+
+    const { pageId } = req.body;
+    try {
+      await crowi.pageService.resumeRenameSubOperation(req.user, pageId);
+    }
+    catch (err) {
+      logger.error(err);
+      return res.apiv3Err(new ErrorV3(`Failed to resume rename operation. ${err}`), 500);
+    }
+    return res.apiv3();
+  });
+
   /**
    * @swagger
    *

+ 31 - 0
packages/app/src/server/service/page.ts

@@ -594,6 +594,37 @@ class PageService {
     await PageOperation.findByIdAndDelete(pageOpId);
   }
 
+  async resumeRenameSubOperation(user: any, pageId: ObjectIdLike): Promise<void> {
+    if (user == null) {
+      throw Error('Guest user cannot execute this operation');
+    }
+
+    // findOne PageOperation
+    const filter = { actionType: PageActionType.Rename, actionStage: PageActionStage.Sub, 'page._id': pageId };
+    const pageOp = await PageOperation.findOne(filter);
+    if (pageOp == null) {
+      throw Error('There is nothing to be processed right now');
+    }
+
+    const { page, toPath, options } = pageOp;
+
+    // check property
+    if (toPath == null) {
+      throw Error(`Property toPath is missing which is needed to resume page operation(${pageOp._id})`);
+    }
+
+    const Page = mongoose.model('Page') as unknown as PageModel;
+
+    // findOne renamed page
+    const renamedPage = await Page.findOne({ _id: page._id }); // sub operation needs renamed page
+    if (renamedPage == null) {
+      throw Error(`Renamed page(${page._id} is not found)`);
+    }
+
+    this.renameSubOperation(page, toPath, user, options, renamedPage, pageOp._id);
+
+  }
+
   private isRenamingToUnderTarget(fromPath: string, toPath: string): boolean {
     const pathToTest = escapeStringRegexp(addTrailingSlash(fromPath));
     const pathToBeTested = toPath;