Просмотр исходного кода

first moved code pages can be delete

ryoji-s 2 лет назад
Родитель
Сommit
df68df58a6

+ 6 - 11
apps/app/src/server/models/page.ts

@@ -958,23 +958,18 @@ schema.statics.findNonEmptyClosestAncestor = async function(path: string): Promi
   return ancestors[0];
 };
 
-schema.statics.removeUserHome = async function(
+schema.statics.findUserHomePage = async function(
     username: string,
-): Promise<{ deleteManyResult: DeleteResult, findOneAndRemoveResult: PageDocument & HasObjectId | null }> {
+): Promise<{ userHomePage: PageDocument & HasObjectId | null }> {
   const userHomePagePath = `/user/${username}`;
 
-  // https://regex101.com/r/PY1tI5/1
-  const regex = new RegExp(`^${userHomePagePath}/.+`);
+  const baseQuery = this.findOne({ path: userHomePagePath });
+  const queryBuilder = new PageQueryBuilder(baseQuery, false);
+  const userHomePage = queryBuilder.query.exec();
 
-  const [deleteManyResult, findOneAndRemoveResult] = await Promise.all([
-    this.deleteMany({ path: regex }),
-    this.findOneAndRemove({ path: userHomePagePath }),
-  ]);
-
-  return { deleteManyResult, findOneAndRemoveResult };
+  return userHomePage;
 };
 
-
 export type PageCreateOptions = {
   format?: string
   grantUserGroupId?: ObjectIdLike

+ 48 - 5
apps/app/src/server/routes/apiv3/users.js

@@ -779,24 +779,67 @@ module.exports = (crowi) => {
     const { id } = req.params;
     const isUserPageDeletionEnabled = crowi.configManager.getConfig('crowi', 'security:isUserPageDeletionEnabled');
 
+    let serializedUserData;
+    let username;
     try {
       const userData = await User.findById(id);
-      const username = userData.username;
+      // !! DO NOT MOVE username FROM THIS POSITION !! -- 05.31.2023
+      // catch username before delete user because username will be change to deleted_at_*
+      username = userData.username;
       await UserGroupRelation.remove({ relatedUser: userData });
       await userData.statusDelete();
       await ExternalAccount.remove({ user: userData });
-      if (isUserPageDeletionEnabled) await Page.removeUserHome(username);
 
-      const serializedUserData = serializeUserSecurely(userData);
+      serializedUserData = serializeUserSecurely(userData);
 
       activityEvent.emit('update', res.locals.activity._id, { action: SupportedAction.ACTION_ADMIN_USERS_REMOVE });
-
-      return res.apiv3({ userData: serializedUserData });
     }
     catch (err) {
       logger.error('Error', err);
       return res.apiv3Err(new ErrorV3(err));
     }
+
+    if (isUserPageDeletionEnabled) {
+      // find userHomePage
+      const userHomePage = await Page.findUserHomePage(username);
+
+      // return error if no deletalbe page
+      if (userHomePage == null) {
+        logger.error('userHomePage is not found');
+        const msg = 'user collection deleted but user home page is not found';
+        return res.apiv3Err(new ErrorV3(msg));
+      }
+
+      // delete completely
+      const isCompletely = true;
+      // delete recursively
+      const isRecursively = true;
+
+      // chack delete completely able userhomepage
+      const pagesToDelete = [userHomePage];
+      const pagesCanBeDeleted = crowi.pageService.filterPagesByCanDeleteCompletely(pagesToDelete, req.user, isRecursively, isUserPageDeletionEnabled);
+
+      // return error if no deletalbe page
+      if (pagesCanBeDeleted.length === 0) {
+        logger.warn('No pages can be deleted.');
+        const msg = 'user collection deleted but no pages can be deleted';
+        return res.apiv3Err(new ErrorV3(msg));
+      }
+
+      // run delete
+      const activityParameters = {
+        ip: req.ip,
+        endpoint: req.originalUrl,
+      };
+      const options = { isCompletely, isRecursively };
+      crowi.pageService.deleteMultiplePages(pagesCanBeDeleted, req.user, options, activityParameters);
+
+      return res.apiv3({
+        userData: serializedUserData, paths: pagesCanBeDeleted.map(p => p.path), isRecursively, isCompletely,
+      });
+    }
+
+    return res.apiv3({ userData: serializedUserData });
   });
 
   /**

+ 4 - 4
apps/app/src/server/service/page.ts

@@ -161,8 +161,8 @@ class PageService {
     this.pageEvent.on('addSeenUsers', this.pageEvent.onAddSeenUsers);
   }
 
-  canDeleteCompletely(path: string, creatorId: ObjectIdLike, operator: any | null, isRecursively: boolean): boolean {
-    if (operator == null || isTopPage(path) || isUsersProtectedPages(path)) return false;
+  canDeleteCompletely(path: string, creatorId: ObjectIdLike, operator: any | null, isRecursively: boolean, isUserPageDeletionEnabled?: boolean): boolean {
+    if (operator == null || isTopPage(path) || isUsersProtectedPages(path, isUserPageDeletionEnabled)) return false;
 
     const pageCompleteDeletionAuthority = this.crowi.configManager.getConfig('crowi', 'security:pageCompleteDeletionAuthority');
     const pageRecursiveCompleteDeletionAuthority = this.crowi.configManager.getConfig('crowi', 'security:pageRecursiveCompleteDeletionAuthority');
@@ -215,8 +215,8 @@ class PageService {
     return false;
   }
 
-  filterPagesByCanDeleteCompletely(pages, user, isRecursively: boolean) {
-    return pages.filter(p => p.isEmpty || this.canDeleteCompletely(p.path, p.creator, user, isRecursively));
+  filterPagesByCanDeleteCompletely(pages, user, isRecursively: boolean, isUserPageDeletionEnabled?: boolean) {
+    return pages.filter(p => p.isEmpty || this.canDeleteCompletely(p.path, p.creator, user, isRecursively, isUserPageDeletionEnabled));
   }
 
   filterPagesByCanDelete(pages, user, isRecursively: boolean) {

+ 2 - 2
packages/core/src/utils/page-path-utils/index.ts

@@ -40,8 +40,8 @@ export const isUsersHomePage = (path: string): boolean => {
  * Whether path is the protected pages for systems
  * @param path
  */
-export const isUsersProtectedPages = (path: string): boolean => {
-  return isUsersTopPage(path) || isUsersHomePage(path);
+export const isUsersProtectedPages = (path: string, isUserPageDeletionEnabled = false): boolean => {
+  return isUsersTopPage(path) || isUserPageDeletionEnabled ? false : isUsersHomePage(path);
 };
 
 /**