Przeglądaj źródła

omit API v1 /pages.update

Yuki Takei 2 lat temu
rodzic
commit
e1714711e6

+ 9 - 54
apps/app/src/client/services/page-operation.ts

@@ -1,10 +1,12 @@
 import { useCallback } from 'react';
 
-import { SubscriptionStatusType, type Nullable } from '@growi/core';
+import { SubscriptionStatusType } from '@growi/core';
 import urljoin from 'url-join';
 
-import type { IApiv3PageCreateParams, IApiv3PageCreateResponse, OptionsToSave } from '~/interfaces/page-operation';
-import { useEditingMarkdown, useIsEnabledUnsavedWarning, usePageTagsForEditors } from '~/stores/editor';
+import type {
+  IApiv3PageCreateParams, IApiv3PageCreateResponse, IApiv3PageUpdateParams, IApiv3PageUpdateResponse,
+} from '~/interfaces/apiv3';
+import { useEditingMarkdown, usePageTagsForEditors } from '~/stores/editor';
 import { useCurrentPageId, useSWRMUTxCurrentPage, useSWRxTagsInfo } from '~/stores/page';
 import { useSetRemoteLatestPageData } from '~/stores/remote-latest-page';
 import loggerFactory from '~/utils/logger';
@@ -15,6 +17,7 @@ import { toastError } from '../util/toastr';
 
 const logger = loggerFactory('growi:services:page-operation');
 
+
 export const toggleSubscribe = async(pageId: string, currentStatus: SubscriptionStatusType | undefined): Promise<void> => {
   try {
     const newStatus = currentStatus === SubscriptionStatusType.SUBSCRIBE
@@ -92,57 +95,9 @@ export const createPage = async(params: IApiv3PageCreateParams): Promise<IApiv3P
   return res.data;
 };
 
-// TODO: define return type
-const updatePage = async(pageId: string, revisionId: string, markdown: string, tmpParams: OptionsToSave) => {
-  // clone
-  const params = Object.assign(tmpParams, {
-    page_id: pageId,
-    revision_id: revisionId,
-    body: markdown,
-  });
-
-  const res: any = await apiPost('/pages.update', params);
-  if (!res.ok) {
-    throw new Error(res.error);
-  }
-  return res;
-};
-
-type PageInfo= {
-  path: string,
-  pageId: Nullable<string>,
-  revisionId: Nullable<string>,
-}
-
-type SaveOrUpdateFunction = (markdown: string, pageInfo: PageInfo, optionsToSave?: OptionsToSave) => any;
-
-// TODO: define return type
-export const useSaveOrUpdate = (): SaveOrUpdateFunction => {
-  /* eslint-disable react-hooks/rules-of-hooks */
-  const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning();
-  /* eslint-enable react-hooks/rules-of-hooks */
-
-  return useCallback(async(markdown: string, pageInfo: PageInfo, optionsToSave?: OptionsToSave) => {
-    const { path, pageId, revisionId } = pageInfo;
-
-    const options: OptionsToSave = Object.assign({}, optionsToSave);
-
-    let res;
-    if (pageId == null || revisionId == null) {
-      res = await createPage({ path, body: markdown, ...options });
-    }
-    else {
-      if (revisionId == null) {
-        const msg = '\'revisionId\' is required to update page';
-        throw new Error(msg);
-      }
-      res = await updatePage(pageId, revisionId, markdown, options);
-    }
-
-    mutateIsEnabledUnsavedWarning(false);
-
-    return res;
-  }, [mutateIsEnabledUnsavedWarning]);
+export const updatePage = async(params: IApiv3PageUpdateParams): Promise<IApiv3PageUpdateResponse> => {
+  const res = await apiv3Put<IApiv3PageUpdateResponse>('/page', params);
+  return res.data;
 };
 
 export type UpdateStateAfterSaveOption = {

+ 0 - 1
apps/app/src/server/routes/index.js

@@ -121,7 +121,6 @@ module.exports = function(crowi, app) {
   apiV1Router.get('/search'                        , accessTokenParser , loginRequired , search.api.search);
 
   // HTTP RPC Styled API (に徐々に移行していいこうと思う)
-  apiV1Router.post('/pages.update'       , accessTokenParser , loginRequiredStrictly , excludeReadOnlyUser, addActivity, page.api.update);
   apiV1Router.get('/pages.exist'         , accessTokenParser , loginRequired , page.api.exist);
   apiV1Router.get('/pages.updatePost'    , accessTokenParser, loginRequired, page.api.getUpdatePost);
   apiV1Router.get('/pages.getPageTag'    , accessTokenParser , loginRequired , page.api.getPageTag);

+ 0 - 157
apps/app/src/server/routes/page.js

@@ -1,7 +1,6 @@
 import { body } from 'express-validator';
 import mongoose from 'mongoose';
 
-import { SupportedTargetModel, SupportedAction } from '~/interfaces/activity';
 import XssOption from '~/services/xss/xssOption';
 import loggerFactory from '~/utils/logger';
 
@@ -9,11 +8,6 @@ import { GlobalNotificationSettingEvent } from '../models';
 import { PathAlreadyExistsError } from '../models/errors';
 import PageTagRelation from '../models/page-tag-relation';
 import UpdatePost from '../models/update-post';
-import { preNotifyService } from '../service/pre-notify';
-
-const { serializePageSecurely } = require('../models/serializers/page-serializer');
-const { serializeRevisionSecurely } = require('../models/serializers/revision-serializer');
-const { serializeUserSecurely } = require('../models/serializers/user-serializer');
 
 /**
  * @swagger
@@ -148,9 +142,6 @@ module.exports = function(crowi, app) {
 
   const { configManager, xssService } = crowi;
   const globalNotificationService = crowi.getGlobalNotificationService();
-  const userNotificationService = crowi.getUserNotificationService();
-
-  const activityEvent = crowi.event('activity');
 
   const Xss = require('~/services/xss/index');
   const initializedConfig = {
@@ -220,154 +211,6 @@ module.exports = function(crowi, app) {
   actions.api = api;
   actions.validator = validator;
 
-  /**
-   * @swagger
-   *
-   *    /pages.update:
-   *      post:
-   *        tags: [Pages, CrowiCompatibles]
-   *        operationId: updatePage
-   *        summary: /pages.update
-   *        description: Update page
-   *        requestBody:
-   *          content:
-   *            application/json:
-   *              schema:
-   *                properties:
-   *                  body:
-   *                    $ref: '#/components/schemas/Revision/properties/body'
-   *                  page_id:
-   *                    $ref: '#/components/schemas/Page/properties/_id'
-   *                  revision_id:
-   *                    $ref: '#/components/schemas/Revision/properties/_id'
-   *                  grant:
-   *                    $ref: '#/components/schemas/Page/properties/grant'
-   *                required:
-   *                  - body
-   *                  - page_id
-   *                  - revision_id
-   *        responses:
-   *          200:
-   *            description: Succeeded to update page.
-   *            content:
-   *              application/json:
-   *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1Response/properties/ok'
-   *                    page:
-   *                      $ref: '#/components/schemas/Page'
-   *                    revision:
-   *                      $ref: '#/components/schemas/Revision'
-   *          403:
-   *            $ref: '#/components/responses/403'
-   *          500:
-   *            $ref: '#/components/responses/500'
-   */
-  /**
-   * @api {post} /pages.update Update page
-   * @apiName UpdatePage
-   * @apiGroup Page
-   *
-   * @apiParam {String} body
-   * @apiParam {String} page_id
-   * @apiParam {String} revision_id
-   * @apiParam {String} grant
-   *
-   * In the case of the page exists:
-   * - If revision_id is specified => update the page,
-   * - If revision_id is not specified => force update by the new contents.
-   */
-  api.update = async function(req, res) {
-    const pageBody = req.body.body ?? null;
-    const pageId = req.body.page_id || null;
-    const revisionId = req.body.revision_id || null;
-    const grant = req.body.grant || null;
-    const userRelatedGrantUserGroupIds = req.body.userRelatedGrantUserGroupIds || null;
-    const overwriteScopesOfDescendants = req.body.overwriteScopesOfDescendants || null;
-    const isSlackEnabled = !!req.body.isSlackEnabled; // cast to boolean
-    const slackChannels = req.body.slackChannels || null;
-
-    if (pageId === null || pageBody === null || revisionId === null) {
-      return res.json(ApiResponse.error('page_id, body and revision_id are required.'));
-    }
-
-    // check page existence
-    const isExist = await Page.count({ _id: pageId }) > 0;
-    if (!isExist) {
-      return res.json(ApiResponse.error(`Page('${pageId}' is not found or forbidden`, 'notfound_or_forbidden'));
-    }
-
-    // check revision
-    const Revision = crowi.model('Revision');
-    let page = await Page.findByIdAndViewer(pageId, req.user);
-    if (page != null && revisionId != null && !page.isUpdatable(revisionId)) {
-      const latestRevision = await Revision.findById(page.revision).populate('author');
-      const returnLatestRevision = {
-        revisionId: latestRevision._id.toString(),
-        revisionBody: xss.process(latestRevision.body),
-        createdAt: latestRevision.createdAt,
-        user: serializeUserSecurely(latestRevision.author),
-      };
-      return res.json(ApiResponse.error('Posted param "revisionId" is outdated.', 'conflict', returnLatestRevision));
-    }
-
-    const options = { overwriteScopesOfDescendants };
-    if (grant != null) {
-      options.grant = grant;
-      options.userRelatedGrantUserGroupIds = userRelatedGrantUserGroupIds;
-    }
-
-    const previousRevision = await Revision.findById(revisionId);
-    try {
-      page = await crowi.pageService.updatePage(page, pageBody, previousRevision.body, req.user, options);
-    }
-    catch (err) {
-      logger.error('error on _api/pages.update', err);
-      return res.json(ApiResponse.error(err));
-    }
-
-
-    const result = {
-      page: serializePageSecurely(page),
-      revision: serializeRevisionSecurely(page.revision),
-    };
-    res.json(ApiResponse.success(result));
-
-    // global notification
-    try {
-      await globalNotificationService.fire(GlobalNotificationSettingEvent.PAGE_EDIT, page, req.user);
-    }
-    catch (err) {
-      logger.error('Edit notification failed', err);
-    }
-
-    // user notification
-    if (isSlackEnabled) {
-      try {
-        const results = await userNotificationService.fire(page, req.user, slackChannels, 'update', { previousRevision });
-        results.forEach((result) => {
-          if (result.status === 'rejected') {
-            logger.error('Create user notification failed', result.reason);
-          }
-        });
-      }
-      catch (err) {
-        logger.error('Create user notification failed', err);
-      }
-    }
-
-    const parameters = {
-      targetModel: SupportedTargetModel.MODEL_PAGE,
-      target: page,
-      action: SupportedAction.ACTION_PAGE_UPDATE,
-    };
-
-    activityEvent.emit(
-      'update', res.locals.activity._id, parameters, { path: page.path, creator: page.creator._id.toString() }, preNotifyService.generatePreNotify,
-    );
-  };
-
   /**
    * @swagger
    *