Procházet zdrojové kódy

Check if parent folder id is valid and add deleted count

https://youtrack.weseek.co.jp/issue/GW-7833
- Update parent type to string in IBookmarkFolderDocument type
- Update return type of deleteFolderAndChildren method
- Check if parent bookmark folder id is valid and parent folder exists
- Add return value of deleteFolderAndChildren method
- Fix delete route parameter and add return value
Mudana-Grune před 3 roky
rodič
revize
7c19f7a31f

+ 15 - 7
packages/app/src/server/models/bookmark-folder.ts

@@ -1,4 +1,5 @@
 import { Ref, IUser } from '@growi/core';
+import { isValidObjectId } from '@growi/core/src/utils/objectid-utils';
 import ExtensibleCustomError from 'extensible-custom-error';
 import {
   Types, Document, Model, Schema,
@@ -16,7 +17,7 @@ export class InvalidParentBookmarkFolder extends ExtensibleCustomError {}
 export type IBookmarkFolderDocument = {
   name: string
   owner: Ref<IUser>
-  parent?: Ref<BookmarkFolderDocument>
+  parent?: string
 }
 export interface BookmarkFolderDocument extends Document {
   _id: Types.ObjectId
@@ -29,7 +30,7 @@ export interface BookmarkFolderModel extends Model<BookmarkFolderDocument>{
   createByParameters(params: IBookmarkFolderDocument): IBookmarkFolderDocument
   findParentFolderByUserId(user: Types.ObjectId | string): IBookmarkFolderDocument[]
   findChildFolderById(parentBookmarkFolder: Types.ObjectId | string): Promise<IBookmarkFolderDocument[]>
-  deleteFolderAndChildren(bookmarkFolderId: string): void
+  deleteFolderAndChildren(bookmarkFolderId: string): {deletedCount: number}
   updateBookmarkFolder(bookmarkFolderId: string, name: string, parent: string): BookmarkFolderDocument | null
 }
 
@@ -48,14 +49,16 @@ bookmarkFolderSchema.statics.createByParameters = async function(params: IBookma
     bookmarkFolder = await this.create({ name, owner, parent:  null }) as unknown as BookmarkFolderDocument;
   }
   else {
+    // Check if parent folder id is valid and parent folder exists
+    const isParentFolderIdValid = isValidObjectId(parent);
     const parentFolder = await this.findById(parent);
-    if (!parentFolder) {
-      throw new InvalidParentBookmarkFolder("Parent folder doesn't exists");
+
+    if (!isParentFolderIdValid || parentFolder == null) {
+      throw new InvalidParentBookmarkFolder("Parent folder id is invalid or parent folder doesn't exists");
     }
     bookmarkFolder = await this.create({ name, owner, parent:  parentFolder?._id }) as unknown as BookmarkFolderDocument;
   }
 
-
   return bookmarkFolder;
 };
 
@@ -70,10 +73,15 @@ bookmarkFolderSchema.statics.findChildFolderById = async function(parentFolderId
   return childFolders;
 };
 
-bookmarkFolderSchema.statics.deleteFolderAndChildren = async function(boookmarkFolderId: string): Promise<void> {
+bookmarkFolderSchema.statics.deleteFolderAndChildren = async function(boookmarkFolderId: Types.ObjectId | string): Promise<{deletedCount: number}> {
   // Delete parent and all children folder
   const bookmarkFolder = await this.findByIdAndDelete(boookmarkFolderId);
-  await this.deleteMany({ parent: bookmarkFolder?.id });
+  let deletedCount = 0;
+  if (bookmarkFolder != null) {
+    const childFolders = await this.deleteMany({ parent: bookmarkFolder?.id });
+    deletedCount = childFolders.deletedCount + 1;
+  }
+  return { deletedCount };
 };
 
 bookmarkFolderSchema.statics.updateBookmarkFolder = async function(bookmarkFolderId: string, name: string, parent: string):

+ 6 - 5
packages/app/src/server/routes/apiv3/bookmark-folder.ts

@@ -15,7 +15,7 @@ const router = express.Router();
 const validator = {
   bookmarkFolder: [
     body('name').isString().withMessage('name must be a string'),
-    body('parent').optional({ nullable: true }),
+    body('parent').isMongoId().optional({ nullable: true }),
   ],
 };
 
@@ -67,11 +67,12 @@ module.exports = (crowi) => {
   });
 
   // Delete bookmark folder and children
-  router.delete('/', accessTokenParser, loginRequiredStrictly, async(req, res) => {
-    const { boookmarkFolderId } = req.body;
+  router.delete('/:id', accessTokenParser, loginRequiredStrictly, async(req, res) => {
+    const { id } = req.params;
     try {
-      await BookmarkFolder.deleteFolderAndChildren(boookmarkFolderId);
-      return res.apiv3();
+      const result = await BookmarkFolder.deleteFolderAndChildren(id);
+      const { deletedCount } = result;
+      return res.apiv3({ deletedCount });
     }
     catch (err) {
       logger.error(err);