From 57a1d03b4bbc4efeac0b6016a2ecfe113e4b461e Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sun, 26 Sep 2021 12:37:07 +0100 Subject: [PATCH] Server: Do not allow accepting share more than once --- packages/server/src/models/ShareUserModel.ts | 4 +++- .../server/src/routes/api/share_users.test.ts | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/server/src/models/ShareUserModel.ts b/packages/server/src/models/ShareUserModel.ts index b50111a72..05db72519 100644 --- a/packages/server/src/models/ShareUserModel.ts +++ b/packages/server/src/models/ShareUserModel.ts @@ -1,5 +1,5 @@ import { Item, Share, ShareType, ShareUser, ShareUserStatus, User, Uuid } from '../services/database/types'; -import { ErrorForbidden, ErrorNotFound } from '../utils/errors'; +import { ErrorBadRequest, ErrorForbidden, ErrorNotFound } from '../utils/errors'; import BaseModel, { AclAction, DeleteOptions } from './BaseModel'; import { getCanShareFolder } from './utils/user'; @@ -117,6 +117,8 @@ export default class ShareUserModel extends BaseModel { const shareUser = await this.byShareAndUserId(shareId, userId); if (!shareUser) throw new ErrorNotFound(`Item has not been shared with this user: ${shareId} / ${userId}`); + if (shareUser.status === status) throw new ErrorBadRequest(`Share ${shareId} status is already ${status}`); + const share = await this.models().share().load(shareId); if (!share) throw new ErrorNotFound(`No such share: ${shareId}`); diff --git a/packages/server/src/routes/api/share_users.test.ts b/packages/server/src/routes/api/share_users.test.ts index d3d6e1116..3c9922439 100644 --- a/packages/server/src/routes/api/share_users.test.ts +++ b/packages/server/src/routes/api/share_users.test.ts @@ -1,8 +1,8 @@ import { ShareType, ShareUserStatus } from '../../services/database/types'; import { beforeAllDb, afterAllTests, beforeEachDb, createUserAndSession, models, createItemTree, expectHttpError } from '../../utils/testing/testUtils'; import { getApi, patchApi } from '../../utils/testing/apiUtils'; -import { shareWithUserAndAccept } from '../../utils/testing/shareApiUtils'; -import { ErrorForbidden } from '../../utils/errors'; +import { shareFolderWithUser, shareWithUserAndAccept } from '../../utils/testing/shareApiUtils'; +import { ErrorBadRequest, ErrorForbidden } from '../../utils/errors'; import { PaginatedResults } from '../../models/utils/pagination'; describe('share_users', function() { @@ -53,4 +53,17 @@ describe('share_users', function() { await expectHttpError(async () => patchApi(session1.id, `share_users/${shareUser.id}`, { status: ShareUserStatus.Accepted }), ErrorForbidden.httpCode); }); + test('should not allow accepting a share twice or more', async function() { + const { session: session1 } = await createUserAndSession(1); + const { session: session2 } = await createUserAndSession(2); + + const { shareUser } = await shareFolderWithUser(session1.id, session2.id, '000000000000000000000000000000F1', { + '000000000000000000000000000000F1': { + '00000000000000000000000000000001': null, + }, + }); + + await expectHttpError(async () => patchApi(session2.id, `share_users/${shareUser.id}`, { status: ShareUserStatus.Accepted }), ErrorBadRequest.httpCode); + }); + });