Преглед изворни кода

Merge pull request #2597 from weseek/imprv/create-apiv3-page-create

Imprv/create apiv3 page create
Yuki Takei пре 5 година
родитељ
комит
0c63ef9226
3 измењених фајлова са 97 додато и 5 уклоњено
  1. 4 5
      src/client/js/services/PageContainer.js
  2. 92 0
      src/server/routes/apiv3/pages.js
  3. 1 0
      src/server/routes/page.js

+ 4 - 5
src/client/js/services/PageContainer.js

@@ -323,11 +323,10 @@ export default class PageContainer extends Container {
       body: markdown,
       body: markdown,
     });
     });
 
 
-    const res = await this.appContainer.apiPost('/pages.create', params);
-    if (!res.ok) {
-      throw new Error(res.error);
-    }
-    return { page: res.page, tags: res.tags };
+    const res = await this.appContainer.apiv3Post('/pages/', params);
+    const { page, tags } = res.data;
+
+    return { page, tags };
   }
   }
 
 
   async updatePage(pageId, revisionId, markdown, tmpParams) {
   async updatePage(pageId, revisionId, markdown, tmpParams) {

+ 92 - 0
src/server/routes/apiv3/pages.js

@@ -3,6 +3,7 @@ const loggerFactory = require('@alias/logger');
 const logger = loggerFactory('growi:routes:apiv3:pages'); // eslint-disable-line no-unused-vars
 const logger = loggerFactory('growi:routes:apiv3:pages'); // eslint-disable-line no-unused-vars
 
 
 const express = require('express');
 const express = require('express');
+const pathUtils = require('growi-commons').pathUtils;
 
 
 
 
 const router = express.Router();
 const router = express.Router();
@@ -15,10 +16,101 @@ const router = express.Router();
 module.exports = (crowi) => {
 module.exports = (crowi) => {
   const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
   const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
   const loginRequired = require('../../middlewares/login-required')(crowi, true);
   const loginRequired = require('../../middlewares/login-required')(crowi, true);
+  const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
   const adminRequired = require('../../middlewares/admin-required')(crowi);
   const adminRequired = require('../../middlewares/admin-required')(crowi);
   const csrf = require('../../middlewares/csrf')(crowi);
   const csrf = require('../../middlewares/csrf')(crowi);
 
 
   const Page = crowi.model('Page');
   const Page = crowi.model('Page');
+  const PageTagRelation = crowi.model('PageTagRelation');
+  const GlobalNotificationSetting = crowi.model('GlobalNotificationSetting');
+
+  const globalNotificationService = crowi.getGlobalNotificationService();
+  const { pageService, slackNotificationService } = crowi;
+
+  // user notification
+  // TODO GW-3387 create '/service/user-notification' module
+  /**
+   *
+   * @param {Page} page
+   * @param {User} user
+   * @param {string} slackChannelsStr comma separated string. e.g. 'general,channel1,channel2'
+   * @param {boolean} updateOrCreate
+   * @param {string} previousRevision
+   */
+  async function notifyToSlackByUser(page, user, slackChannelsStr, updateOrCreate, previousRevision) {
+    await page.updateSlackChannel(slackChannelsStr)
+      .catch((err) => {
+        logger.error('Error occured in updating slack channels: ', err);
+      });
+
+
+    if (slackNotificationService.hasSlackConfig()) {
+      const slackChannels = slackChannelsStr != null ? slackChannelsStr.split(',') : [null];
+
+      const promises = slackChannels.map((chan) => {
+        return crowi.slack.postPage(page, user, chan, updateOrCreate, previousRevision);
+      });
+
+      Promise.all(promises)
+        .catch((err) => {
+          logger.error('Error occured in sending slack notification: ', err);
+        });
+    }
+  }
+
+  // TODO write swagger(GW-3384) and validation(GW-3385)
+  router.post('/', accessTokenParser, loginRequiredStrictly, csrf, async(req, res) => {
+    const {
+      body, grant, grantUserGroupId, overwriteScopesOfDescendants, isSlackEnabled, slackChannels, socketClientId, pageTags,
+    } = req.body;
+    let { path } = req.body;
+
+    // check whether path starts slash
+    path = pathUtils.addHeadingSlash(path);
+
+    // check page existence
+    const isExist = await Page.count({ path }) > 0;
+    if (isExist) {
+      res.code = 'page_exists';
+      return res.apiv3Err('Page exists', 409);
+    }
+
+    const options = { socketClientId };
+    if (grant != null) {
+      options.grant = grant;
+      options.grantUserGroupId = grantUserGroupId;
+    }
+
+    const createdPage = await Page.create(path, body, req.user, options);
+
+    let savedTags;
+    if (pageTags != null) {
+      await PageTagRelation.updatePageTags(createdPage.id, pageTags);
+      savedTags = await PageTagRelation.listTagNamesByPage(createdPage.id);
+    }
+
+    const result = { page: pageService.serializeToObj(createdPage), tags: savedTags };
+
+    // update scopes for descendants
+    if (overwriteScopesOfDescendants) {
+      Page.applyScopesToDescendantsAsyncronously(createdPage, req.user);
+    }
+
+    // global notification
+    try {
+      await globalNotificationService.fire(GlobalNotificationSetting.EVENT.PAGE_CREATE, createdPage, req.user);
+    }
+    catch (err) {
+      logger.error('Create notification failed', err);
+    }
+
+    // user notification
+    if (isSlackEnabled) {
+      await notifyToSlackByUser(createdPage, req.user, slackChannels, 'create', false);
+    }
+
+    return res.apiv3(result);
+  });
 
 
   /**
   /**
    * @swagger
    * @swagger

+ 1 - 0
src/server/routes/page.js

@@ -672,6 +672,7 @@ module.exports = function(crowi, app) {
    * @apiParam {String} grant
    * @apiParam {String} grant
    * @apiParam {Array} pageTags
    * @apiParam {Array} pageTags
    */
    */
+  // TODO If everything that depends on this route, delete it too
   api.create = async function(req, res) {
   api.create = async function(req, res) {
     const body = req.body.body || null;
     const body = req.body.body || null;
     let pagePath = req.body.path || null;
     let pagePath = req.body.path || null;