Skip to content

Commit

Permalink
Merge pull request #9082 from weseek/master
Browse files Browse the repository at this point in the history
Release v7.0.19
  • Loading branch information
yuki-takei authored Sep 12, 2024
2 parents 6da3e2d + 12ae2d3 commit 357ad1a
Show file tree
Hide file tree
Showing 15 changed files with 67 additions and 35 deletions.
14 changes: 3 additions & 11 deletions .github/mergify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,11 @@ queue_rules:
allow_inplace_checks: false
queue_conditions:
- '#check-failure = 0'
- or:
- and:
- check-success ~= ci-slackbot-proxy-
- and:
- check-success ~= ci-app-
- check-success ~= ci-app-
merge_conditions:
- '#check-failure = 0'
- or:
- and:
- check-success ~= ci-slackbot-proxy-
- and:
- check-success ~= ci-app-
- check-success ~= test-prod-node20 /
- check-success ~= ci-app-
- check-success ~= test-prod-node20 /

pull_request_rules:
- name: Automatic queue to merge
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci-app-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ on:
- master
- dev/7.*.x
- dev/6.*.x
- release/*
types: [opened, reopened, synchronize]
paths:
- .github/mergify.yml
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,11 @@ jobs:
yarn global add node-gyp
yarn --frozen-lockfile
- name: turbo run dev:ci
- name: turbo run launch-dev:ci
working-directory: ./apps/app
run: |
cp config/ci/.env.local.for-ci .env.development.local
turbo run dev:ci --env-mode=loose
turbo run launch-dev:ci --env-mode=loose
env:
MONGO_URI: mongodb://localhost:${{ job.services.mongodb.ports['27017'] }}/growi_dev

Expand Down
4 changes: 2 additions & 2 deletions apps/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@growi/app",
"version": "7.0.18",
"version": "7.0.19-RC.0",
"license": "MIT",
"private": "true",
"scripts": {
Expand All @@ -26,7 +26,7 @@
"dev:migrate:up": "yarn dev:migrate-mongo up -f config/migrate-mongo-config.js",
"dev:migrate:down": "yarn dev:migrate-mongo down -f config/migrate-mongo-config.js",
"//// for CI": "",
"dev:ci": "yarn cross-env NODE_ENV=development yarn ts-node src/server/app.ts --ci",
"launch-dev:ci": "yarn cross-env NODE_ENV=development yarn dev:migrate && yarn ts-node src/server/app.ts --ci",
"lint:typecheck": "npx -y tspc",
"lint:eslint": "yarn eslint --quiet \"**/*.{js,jsx,ts,tsx}\"",
"lint:styles": "stylelint \"src/**/*.scss\"",
Expand Down
6 changes: 6 additions & 0 deletions apps/app/playwright/40-admin/access-to-admin-page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ test('admin/export is successfully loaded', async({ page }) => {
await expect(page.getByTestId('admin-export-archive-data')).toBeVisible();
});

test('admin/data-transfer is successfully loaded', async({ page }) => {
await page.goto('/admin/data-transfer');

await expect(page.getByTestId('admin-export-archive-data')).toBeVisible();
});

test('admin/notification is successfully loaded', async({ page }) => {
await page.goto('/admin/notification');

Expand Down
8 changes: 6 additions & 2 deletions apps/app/src/client/components/PageComment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,12 @@ export const PageComment: FC<PageCommentProps> = memo((props: PageCommentProps):
onDeleteCommentAfterOperation();
}
catch (error: unknown) {
setErrorMessageOnDelete(error as string);
toastError(`error: ${error}`);
const message = error instanceof Error
? error.message
: (error as any).toString();

setErrorMessageOnDelete(message);
toastError(message);
}
}, [commentToBeDeleted, onDeleteCommentAfterOperation]);

Expand Down
1 change: 1 addition & 0 deletions apps/app/src/interfaces/apiv3/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ export type IApiv3PageUpdateResponse = {

export const PageUpdateErrorCode = {
CONFLICT: 'conflict',
FORBIDDEN: 'forbidden',
} as const;
1 change: 1 addition & 0 deletions apps/app/src/server/models/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface PageDocument extends IPage, Document<Types.ObjectId> {
[x:string]: any // for obsolete methods
getLatestRevisionBodyLength(): Promise<number | null | undefined>
calculateAndUpdateLatestRevisionBodyLength(this: PageDocument): Promise<void>
populateDataToShowRevision(shouldExcludeBody?: boolean): Promise<PageDocument>
}


Expand Down
20 changes: 15 additions & 5 deletions apps/app/src/server/routes/apiv3/page/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { excludeReadOnlyUser } from '~/server/middlewares/exclude-read-only-user
import { GlobalNotificationSettingEvent } from '~/server/models/GlobalNotificationSetting';
import type { PageDocument, PageModel } from '~/server/models/page';
import { Revision } from '~/server/models/revision';
import ShareLink from '~/server/models/share-link';
import Subscription from '~/server/models/subscription';
import { configManager } from '~/server/service/config-manager';
import type { IPageGrantService } from '~/server/service/page-grant';
Expand Down Expand Up @@ -202,6 +203,7 @@ module.exports = (crowi) => {
query('pageId').optional().isString(),
query('path').optional().isString(),
query('findAll').optional().isBoolean(),
query('shareLinkId').optional().isMongoId(),
],
likes: [
body('pageId').isString(),
Expand Down Expand Up @@ -284,19 +286,27 @@ module.exports = (crowi) => {
* $ref: '#/components/schemas/Page'
*/
router.get('/', certifySharedPage, accessTokenParser, loginRequired, validator.getPage, apiV3FormValidator, async(req, res) => {
const { user } = req;
const { user, isSharedPage } = req;
const {
pageId, path, findAll, revisionId,
pageId, path, findAll, revisionId, shareLinkId,
} = req.query;

if (pageId == null && path == null) {
return res.apiv3Err(new ErrorV3('Either parameter of path or pageId is required.', 'invalid-request'));
const isValid = (shareLinkId != null && pageId != null && path == null) || (shareLinkId == null && (pageId != null || path != null));
if (!isValid) {
return res.apiv3Err(new Error('Either parameter of (pageId or path) or (pageId and shareLinkId) is required.'), 400);
}

let page;
let pages;
try {
if (pageId != null) { // prioritized
if (isSharedPage) {
const shareLink = await ShareLink.findOne({ _id: shareLinkId });
if (shareLink == null) {
throw new Error('ShareLink is not found');
}
page = await Page.findOne({ _id: getIdForRef(shareLink.relatedPage) });
}
else if (pageId != null) { // prioritized
page = await Page.findByIdAndViewer(pageId, user);
}
else if (!findAll) {
Expand Down
12 changes: 10 additions & 2 deletions apps/app/src/server/routes/apiv3/page/update-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
} from '@growi/core';
import { ErrorV3 } from '@growi/core/dist/models';
import { serializeUserSecurely } from '@growi/core/dist/models/serializers';
import { isTopPage, isUsersProtectedPages } from '@growi/core/dist/utils/page-path-utils';
import type { Request, RequestHandler } from 'express';
import type { ValidationChain } from 'express-validator';
import { body } from 'express-validator';
Expand All @@ -27,6 +28,7 @@ import { apiV3FormValidator } from '../../../middlewares/apiv3-form-validator';
import { excludeReadOnlyUser } from '../../../middlewares/exclude-read-only-user';
import type { ApiV3Response } from '../interfaces/apiv3-response';


const logger = loggerFactory('growi:routes:apiv3:page:update-page');


Expand Down Expand Up @@ -121,7 +123,7 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
validator, apiV3FormValidator,
async(req: UpdatePageRequest, res: ApiV3Response) => {
const {
pageId, revisionId, body, origin,
pageId, revisionId, body, origin, grant,
} = req.body;

const sanitizeRevisionId = revisionId == null ? undefined : generalXssFilter.process(revisionId);
Expand All @@ -139,6 +141,12 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
return res.apiv3Err(new ErrorV3(`Page('${pageId}' is not found or forbidden`, 'notfound_or_forbidden'), 400);
}

const isGrantImmutable = isTopPage(currentPage.path) || isUsersProtectedPages(currentPage.path);

if (grant != null && grant !== currentPage.grant && isGrantImmutable) {
return res.apiv3Err(new ErrorV3('The grant settings for the specified page cannot be modified.', PageUpdateErrorCode.FORBIDDEN), 403);
}

if (currentPage != null) {
// Normalize the latest revision which was borken by the migration script '20211227060705-revision-path-to-page-id-schema-migration--fixed-7549.js'
try {
Expand All @@ -164,7 +172,7 @@ export const updatePageHandlersFactory: UpdatePageHandlersFactory = (crowi) => {
let previousRevision: IRevisionHasId | null;
try {
const {
grant, userRelatedGrantUserGroupIds, overwriteScopesOfDescendants, wip,
userRelatedGrantUserGroupIds, overwriteScopesOfDescendants, wip,
} = req.body;
const options: IOptionsForUpdate = { overwriteScopesOfDescendants, origin, wip };
if (grant != null) {
Expand Down
7 changes: 4 additions & 3 deletions apps/app/src/server/routes/comment.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

import { getIdStringForRef } from '@growi/core';
import { serializeUserSecurely } from '@growi/core/dist/models/serializers';

import { Comment, CommentEvent, commentEvent } from '~/features/comment/server';
Expand Down Expand Up @@ -56,7 +57,6 @@ module.exports = function(crowi, app) {
const logger = loggerFactory('growi:routes:comment');
const User = crowi.model('User');
const Page = crowi.model('Page');
const GlobalNotificationSetting = crowi.model('GlobalNotificationSetting');
const ApiResponse = require('../util/apiResponse');

const activityEvent = crowi.event('activity');
Expand Down Expand Up @@ -465,19 +465,20 @@ module.exports = function(crowi, app) {
}

try {
/** @type {import('mongoose').HydratedDocument<import('~/interfaces/comment').IComment>} */
const comment = await Comment.findById(commentId).exec();

if (comment == null) {
throw new Error('This comment does not exist.');
}

// check whether accessible
const pageId = comment.page;
const pageId = getIdStringForRef(comment.page);
const isAccessible = await Page.isAccessiblePageByViewer(pageId, req.user);
if (!isAccessible) {
throw new Error('Current user is not accessible to this page.');
}
if (req.user._id !== comment.creator.toString()) {
if (getIdStringForRef(req.user) !== getIdStringForRef(comment.creator)) {
throw new Error('Current user is not operatable to this comment.');
}

Expand Down
15 changes: 11 additions & 4 deletions apps/app/src/stores/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,14 @@ export const useTemplateBodyData = (initialData?: string): SWRResponse<string, E
export const useSWRxCurrentPage = (initialData?: IPagePopulatedToShowRevision|null): SWRResponse<IPagePopulatedToShowRevision|null> => {
const key = 'currentPage';

const { data: isLatestRevision } = useIsLatestRevision();

const { cache } = useSWRConfig();

// Problem 1: https://github.com/weseek/growi/pull/7772/files#diff-4c1708c4f959974166c15435c6b35950ba01bbf35e7e4b8e99efeb125a8000a7
// Problem 2: https://redmine.weseek.co.jp/issues/141027
// Problem 3: https://redmine.weseek.co.jp/issues/153618
// Problem 4: https://redmine.weseek.co.jp/issues/153759
const shouldMutate = (() => {
if (initialData === undefined) {
return false;
Expand All @@ -81,8 +85,11 @@ export const useSWRxCurrentPage = (initialData?: IPagePopulatedToShowRevision|nu
return true;
}

// mutate When a different revision is opened
if (cachedData.revision?._id != null && initialData.revision?._id != null && cachedData.revision._id !== initialData.revision._id) {
// mutate when opening a previous revision.
if (!isLatestRevision
&& cachedData.revision?._id != null && initialData.revision?._id != null
&& cachedData.revision._id !== initialData.revision._id
) {
return true;
}

Expand Down Expand Up @@ -285,7 +292,7 @@ export const useSWRxCurrentGrantData = (
? ['/page/grant-data', pageId]
: null;

return useSWRImmutable(
return useSWR(
key,
([endpoint, pageId]) => apiv3Get(endpoint, { pageId }).then(response => response.data),
);
Expand All @@ -295,7 +302,7 @@ export const useSWRxApplicableGrant = (
pageId: string | null | undefined,
): SWRResponse<IRecordApplicableGrant, Error> => {

return useSWRImmutable(
return useSWR(
pageId != null ? ['/page/applicable-grant', pageId] : null,
([endpoint, pageId]) => apiv3Get(endpoint, { pageId }).then(response => response.data),
);
Expand Down
5 changes: 3 additions & 2 deletions apps/app/turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@
"cache": false,
"persistent": true
},
"dev:ci": {
"dependsOn": ["^dev", "dev:migrate", "dev:styles-prebuilt"],

"launch-dev:ci": {
"dependsOn": ["^dev", "dev:styles-prebuilt"],
"cache": false
},

Expand Down
2 changes: 1 addition & 1 deletion apps/slackbot-proxy/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@growi/slackbot-proxy",
"version": "7.0.18-slackbot-proxy.0",
"version": "7.0.19-slackbot-proxy.0",
"license": "MIT",
"private": "true",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "growi",
"version": "7.0.18",
"version": "7.0.19-RC.0",
"description": "Team collaboration software using markdown",
"license": "MIT",
"private": "true",
Expand Down

0 comments on commit 357ad1a

Please sign in to comment.