|
@@ -1,3 +1,4 @@
|
|
|
|
|
+import { allOrigin } from '@growi/core';
|
|
|
import type {
|
|
import type {
|
|
|
IPage, IRevisionHasId, IUserHasId,
|
|
IPage, IRevisionHasId, IUserHasId,
|
|
|
} from '@growi/core';
|
|
} from '@growi/core';
|
|
@@ -8,7 +9,7 @@ import { body } from 'express-validator';
|
|
|
import mongoose from 'mongoose';
|
|
import mongoose from 'mongoose';
|
|
|
|
|
|
|
|
import { SupportedAction, SupportedTargetModel } from '~/interfaces/activity';
|
|
import { SupportedAction, SupportedTargetModel } from '~/interfaces/activity';
|
|
|
-import type { IApiv3PageUpdateParams } from '~/interfaces/apiv3';
|
|
|
|
|
|
|
+import { type IApiv3PageUpdateParams } from '~/interfaces/apiv3';
|
|
|
import type { IOptionsForUpdate } from '~/interfaces/page';
|
|
import type { IOptionsForUpdate } from '~/interfaces/page';
|
|
|
import { RehypeSanitizeOption } from '~/interfaces/rehype';
|
|
import { RehypeSanitizeOption } from '~/interfaces/rehype';
|
|
|
import type Crowi from '~/server/crowi';
|
|
import type Crowi from '~/server/crowi';
|
|
@@ -63,7 +64,8 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
|
|
|
const validator: ValidationChain[] = [
|
|
const validator: ValidationChain[] = [
|
|
|
body('pageId').exists().not().isEmpty({ ignore_whitespace: true })
|
|
body('pageId').exists().not().isEmpty({ ignore_whitespace: true })
|
|
|
.withMessage("'pageId' must be specified"),
|
|
.withMessage("'pageId' must be specified"),
|
|
|
- body('revisionId').exists().not().isEmpty({ ignore_whitespace: true })
|
|
|
|
|
|
|
+ body('revisionId').optional().exists().not()
|
|
|
|
|
+ .isEmpty({ ignore_whitespace: true })
|
|
|
.withMessage("'revisionId' must be specified"),
|
|
.withMessage("'revisionId' must be specified"),
|
|
|
body('body').exists().isString()
|
|
body('body').exists().isString()
|
|
|
.withMessage("The empty value is not allowd for the 'body'"),
|
|
.withMessage("The empty value is not allowd for the 'body'"),
|
|
@@ -72,6 +74,7 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
|
|
|
body('overwriteScopesOfDescendants').optional().isBoolean().withMessage('overwriteScopesOfDescendants must be boolean'),
|
|
body('overwriteScopesOfDescendants').optional().isBoolean().withMessage('overwriteScopesOfDescendants must be boolean'),
|
|
|
body('isSlackEnabled').optional().isBoolean().withMessage('isSlackEnabled must be boolean'),
|
|
body('isSlackEnabled').optional().isBoolean().withMessage('isSlackEnabled must be boolean'),
|
|
|
body('slackChannels').optional().isString().withMessage('slackChannels must be string'),
|
|
body('slackChannels').optional().isString().withMessage('slackChannels must be string'),
|
|
|
|
|
+ body('origin').optional().isIn(allOrigin).withMessage('origin must be "view" or "editor"'),
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
@@ -101,7 +104,8 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
|
|
|
const { revisionId, isSlackEnabled, slackChannels } = req.body;
|
|
const { revisionId, isSlackEnabled, slackChannels } = req.body;
|
|
|
if (isSlackEnabled) {
|
|
if (isSlackEnabled) {
|
|
|
try {
|
|
try {
|
|
|
- const results = await crowi.userNotificationService.fire(updatedPage, req.user, slackChannels, 'update', { previousRevision: revisionId });
|
|
|
|
|
|
|
+ const option = revisionId != null ? { previousRevision: revisionId } : undefined;
|
|
|
|
|
+ const results = await crowi.userNotificationService.fire(updatedPage, req.user, slackChannels, 'update', option);
|
|
|
results.forEach((result) => {
|
|
results.forEach((result) => {
|
|
|
if (result.status === 'rejected') {
|
|
if (result.status === 'rejected') {
|
|
|
logger.error('Create user notification failed', result.reason);
|
|
logger.error('Create user notification failed', result.reason);
|
|
@@ -120,7 +124,9 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
|
|
|
accessTokenParser, loginRequiredStrictly, excludeReadOnlyUser, addActivity,
|
|
accessTokenParser, loginRequiredStrictly, excludeReadOnlyUser, addActivity,
|
|
|
validator, apiV3FormValidator,
|
|
validator, apiV3FormValidator,
|
|
|
async(req: UpdatePageRequest, res: ApiV3Response) => {
|
|
async(req: UpdatePageRequest, res: ApiV3Response) => {
|
|
|
- const { pageId, revisionId, body } = req.body;
|
|
|
|
|
|
|
+ const {
|
|
|
|
|
+ pageId, revisionId, body, origin,
|
|
|
|
|
+ } = req.body;
|
|
|
|
|
|
|
|
// check page existence
|
|
// check page existence
|
|
|
const isExist = await Page.count({ _id: pageId }) > 0;
|
|
const isExist = await Page.count({ _id: pageId }) > 0;
|
|
@@ -130,7 +136,7 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
|
|
|
|
|
|
|
|
// check revision
|
|
// check revision
|
|
|
const currentPage = await Page.findByIdAndViewer(pageId, req.user);
|
|
const currentPage = await Page.findByIdAndViewer(pageId, req.user);
|
|
|
- if (currentPage != null && !currentPage.isUpdatable(revisionId)) {
|
|
|
|
|
|
|
+ if (currentPage != null && !currentPage.isUpdatable(revisionId, origin)) {
|
|
|
const latestRevision = await Revision.findById(currentPage.revision).populate('author');
|
|
const latestRevision = await Revision.findById(currentPage.revision).populate('author');
|
|
|
const returnLatestRevision = {
|
|
const returnLatestRevision = {
|
|
|
revisionId: latestRevision?._id.toString(),
|
|
revisionId: latestRevision?._id.toString(),
|
|
@@ -146,7 +152,7 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
|
|
|
let updatedPage;
|
|
let updatedPage;
|
|
|
try {
|
|
try {
|
|
|
const { grant, userRelatedGrantUserGroupIds, overwriteScopesOfDescendants } = req.body;
|
|
const { grant, userRelatedGrantUserGroupIds, overwriteScopesOfDescendants } = req.body;
|
|
|
- const options: IOptionsForUpdate = { overwriteScopesOfDescendants };
|
|
|
|
|
|
|
+ const options: IOptionsForUpdate = { overwriteScopesOfDescendants, origin };
|
|
|
if (grant != null) {
|
|
if (grant != null) {
|
|
|
options.grant = grant;
|
|
options.grant = grant;
|
|
|
options.userRelatedGrantUserGroupIds = userRelatedGrantUserGroupIds;
|
|
options.userRelatedGrantUserGroupIds = userRelatedGrantUserGroupIds;
|