From 07ae120e2adae8879fc779d885076efb9dbe207d Mon Sep 17 00:00:00 2001 From: Mo Date: Wed, 31 May 2023 16:07:13 -0500 Subject: [PATCH] refactor(wip): vault system identifier --- .../common/src/Domain/Content/ContentType.ts | 2 +- .../1684528646896-create_vault_invites.ts | 2 +- .../Bootstrap/ServerContainerConfigLoader.ts | 6 +- .../syncing-server/src/Bootstrap/Types.ts | 1 - .../src/Controller/GroupInvitesController.ts | 4 +- .../src/Controller/GroupsController.ts | 95 ++++-- .../src/Domain/Group/Factory/GroupFactory.ts | 1 + .../src/Domain/Group/Factory/GroupHash.ts | 1 + .../src/Domain/Group/Model/Group.ts | 6 + .../src/Domain/Group/Service/GroupService.ts | 58 +++- .../Group/Service/GroupServiceInterface.ts | 11 +- .../GroupInvite/Factory/GroupInviteFactory.ts | 2 +- .../GroupInvite/Factory/GroupInviteHash.ts | 2 +- .../Domain/GroupInvite/Model/GroupInvite.ts | 4 +- .../GroupInvite/Service/CreateInviteDTO.ts | 2 +- .../GroupInvite/Service/GroupInviteService.ts | 4 +- .../Service/GroupInviteServiceInterface.ts | 15 +- .../GroupInvite/Service/UpdateInviteDTO.ts | 2 +- .../syncing-server/src/Domain/Item/Item.ts | 50 ++-- .../src/Domain/Item/ItemFactory.ts | 4 +- .../src/Domain/Item/ItemHash.ts | 2 +- .../src/Domain/Item/ItemService.ts | 48 +-- .../src/Domain/Item/ItemServiceInterface.ts | 2 + .../src/Domain/Item/SaveRule/GroupFilter.ts | 274 +++--------------- .../Item/SaveRule/GroupSaveOperation.ts | 44 --- .../Item/SaveRule/GroupSnjsVersionFilter.ts | 2 +- .../Domain/Item/SaveRule/OwnershipFilter.ts | 2 +- .../GetGlobalItem/GetGlobalItem.spec.ts | 35 --- .../UseCase/GetGlobalItem/GetGlobalItem.ts | 24 -- .../UseCase/GetGlobalItem/GetGlobalItemDTO.ts | 3 - .../GetGlobalItem/GetGlobalItemResponse.ts | 11 - .../src/Projection/GroupInviteProjection.ts | 2 +- .../src/Projection/GroupInviteProjector.ts | 2 +- .../syncing-server/src/Tmp/ConflictType.ts | 3 +- 34 files changed, 233 insertions(+), 493 deletions(-) delete mode 100644 packages/syncing-server/src/Domain/Item/SaveRule/GroupSaveOperation.ts delete mode 100644 packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItem.spec.ts delete mode 100644 packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItem.ts delete mode 100644 packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItemDTO.ts delete mode 100644 packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItemResponse.ts diff --git a/packages/common/src/Domain/Content/ContentType.ts b/packages/common/src/Domain/Content/ContentType.ts index cb2350deb..1443a26b0 100644 --- a/packages/common/src/Domain/Content/ContentType.ts +++ b/packages/common/src/Domain/Content/ContentType.ts @@ -3,7 +3,7 @@ export enum ContentType { Any = '*', Item = 'SF|Item', VaultItemsKey = 'SN|VaultItemsKey', - VaultKey = 'SN|VaultKey', + VaultKeyCopy = 'SN|VaultKeyCopy', TrustedContact = 'SN|TrustedContact', RootKey = 'SN|RootKey|NoSync', ItemsKey = 'SN|ItemsKey', diff --git a/packages/syncing-server/migrations/mysql/1684528646896-create_vault_invites.ts b/packages/syncing-server/migrations/mysql/1684528646896-create_vault_invites.ts index 1581da4ff..333301e7a 100644 --- a/packages/syncing-server/migrations/mysql/1684528646896-create_vault_invites.ts +++ b/packages/syncing-server/migrations/mysql/1684528646896-create_vault_invites.ts @@ -44,7 +44,7 @@ export class CreateGroupInvites1684528646896 implements MigrationInterface { isNullable: false, }), new TableColumn({ - name: 'encrypted_group_data', + name: 'encrypted_vault_key_content', type: 'text', isNullable: false, }), diff --git a/packages/syncing-server/src/Bootstrap/ServerContainerConfigLoader.ts b/packages/syncing-server/src/Bootstrap/ServerContainerConfigLoader.ts index 221828858..c4ce097ec 100644 --- a/packages/syncing-server/src/Bootstrap/ServerContainerConfigLoader.ts +++ b/packages/syncing-server/src/Bootstrap/ServerContainerConfigLoader.ts @@ -1,4 +1,3 @@ -import { GetGlobalItem } from './../Domain/UseCase/GetGlobalItem/GetGlobalItem' import { ContactFactory } from './../Domain/Contact/Factory/ContactFactory' import { GroupServiceInterface } from '../Domain/Group/Service/GroupServiceInterface' @@ -114,9 +113,6 @@ export class ServerContainerConfigLoader extends CommonContainerConfigLoader { container.bind(TYPES.GetItem).toDynamicValue((context: interfaces.Context) => { return new GetItem(context.container.get(TYPES.ItemRepository)) }) - container.bind(TYPES.GetGlobalItem).toDynamicValue((context: interfaces.Context) => { - return new GetGlobalItem(context.container.get(TYPES.ItemRepository)) - }) container .bind(TYPES.CreateGroupFileReadValetToken) @@ -148,7 +144,6 @@ export class ServerContainerConfigLoader extends CommonContainerConfigLoader { context.container.get(TYPES.ItemProjector), context.container.get(TYPES.MAX_ITEMS_LIMIT), context.container.get(TYPES.GroupUserRepository), - context.container.get(TYPES.GroupService), context.container.get(TYPES.Logger), ) }) @@ -159,6 +154,7 @@ export class ServerContainerConfigLoader extends CommonContainerConfigLoader { context.container.get(TYPES.GroupFactory), context.container.get(TYPES.GroupUserService), context.container.get(TYPES.GroupInviteService), + context.container.get(TYPES.ItemService), context.container.get(TYPES.Timer), ) }) diff --git a/packages/syncing-server/src/Bootstrap/Types.ts b/packages/syncing-server/src/Bootstrap/Types.ts index 10ed7c773..2d4bdebbf 100644 --- a/packages/syncing-server/src/Bootstrap/Types.ts +++ b/packages/syncing-server/src/Bootstrap/Types.ts @@ -74,7 +74,6 @@ const TYPES = { SyncItems: Symbol.for('SyncItems'), CheckIntegrity: Symbol.for('CheckIntegrity'), GetItem: Symbol.for('GetItem'), - GetGlobalItem: Symbol.for('GetGlobalItem'), CreateGroupFileReadValetToken: Symbol.for('CreateGroupFileReadValetToken'), // Handlers UserCredentialsChangedEventHandler: Symbol.for('UserCredentialsChangedEventHandler'), diff --git a/packages/syncing-server/src/Controller/GroupInvitesController.ts b/packages/syncing-server/src/Controller/GroupInvitesController.ts index 288c34bb1..dd92be3ef 100644 --- a/packages/syncing-server/src/Controller/GroupInvitesController.ts +++ b/packages/syncing-server/src/Controller/GroupInvitesController.ts @@ -32,7 +32,7 @@ export class GroupInvitesController extends BaseHttpController { groupUuid: request.params.groupUuid, userUuid: request.body.invitee_uuid, inviterPublicKey: request.body.inviter_public_key, - encryptedGroupData: request.body.encrypted_group_data, + encryptedVaultKeyContent: request.body.encrypted_vault_key_content, inviteType: request.body.invite_type, permissions: request.body.permissions, }) @@ -53,7 +53,7 @@ export class GroupInvitesController extends BaseHttpController { originatorUuid: response.locals.user.uuid, inviteUuid: request.params.inviteUuid, inviterPublicKey: request.body.inviter_public_key, - encryptedGroupData: request.body.encrypted_group_data, + encryptedVaultKeyContent: request.body.encrypted_vault_key_content, permissions: request.body.permissions, }) diff --git a/packages/syncing-server/src/Controller/GroupsController.ts b/packages/syncing-server/src/Controller/GroupsController.ts index 3db066d48..6538de625 100644 --- a/packages/syncing-server/src/Controller/GroupsController.ts +++ b/packages/syncing-server/src/Controller/GroupsController.ts @@ -18,6 +18,8 @@ import { GroupProjection } from '../Projection/GroupProjection' import { GroupUserProjection } from '../Projection/GroupUserProjection' import { CreateGroupFileValetToken } from '../Domain/UseCase/CreateGroupFileValetToken/CreateGroupFileValetToken' import { RemovedGroupUserServiceInterface } from '../Domain/RemovedGroupUser/Service/RemovedGroupUserServiceInterface' +import { Item } from '../Domain/Item/Item' +import { ItemProjection } from '../Projection/ItemProjection' @controller('/groups') export class GroupsController extends BaseHttpController { @@ -27,6 +29,7 @@ export class GroupsController extends BaseHttpController { @inject(TYPES.GroupProjector) private groupProjector: ProjectorInterface, @inject(TYPES.GroupUserProjector) private groupUserProjector: ProjectorInterface, @inject(TYPES.CreateGroupFileReadValetToken) private createGroupFileReadValetToken: CreateGroupFileValetToken, + @inject(TYPES.ItemProjector) private itemProjector: ProjectorInterface, ) { super() } @@ -42,36 +45,11 @@ export class GroupsController extends BaseHttpController { }) } - @httpPost('/:groupUuid/valet-tokens', TYPES.AuthMiddleware) - public async getValetTokenForGroupFile( - request: Request, - response: Response, - ): Promise { - const valetTokenResult = await this.createGroupFileReadValetToken.execute({ - userUuid: response.locals.user.uuid, - groupUuid: request.params.groupUuid, - fileUuid: request.body.file_uuid, - remoteIdentifier: request.body.remote_identifier, - operation: request.body.operation, - unencryptedFileSize: request.body.unencrypted_file_size, - moveOperationType: request.body.move_operation_type, - groupToGroupMoveTargetUuid: request.body.group_to_group_move_target_uuid, - }) - - if (valetTokenResult.success === false) { - return this.errorResponse(400, `Failed to create group valet token: ${valetTokenResult.reason}`) - } - - return this.json({ - valetToken: valetTokenResult.valetToken, - }) - } - @httpPost('/', TYPES.AuthMiddleware) public async createGroup(request: Request, response: Response): Promise { const result = await this.groupService.createGroup({ userUuid: response.locals.user.uuid, - groupUuid: request.body.group_uuid, + vaultSystemIdentifier: request.body.vault_system_identifier, specifiedItemsKeyUuid: request.body.specified_items_key_uuid, }) @@ -116,6 +94,46 @@ export class GroupsController extends BaseHttpController { return this.json({ success: true }) } + @httpPost('/:groupUuid/items', TYPES.AuthMiddleware) + public async addItemToGroup( + request: Request, + response: Response, + ): Promise { + const result = await this.groupService.addItemToGroup({ + groupUuid: request.params.groupUuid, + itemUuid: request.body.item_uuid, + originatorUuid: response.locals.user.uuid, + }) + + if (!result) { + return this.errorResponse(400, 'Could not add item to group') + } + + return this.json({ + item: this.itemProjector.projectFull(result), + }) + } + + @httpDelete('/:groupUuid/items', TYPES.AuthMiddleware) + public async removeItemFromGroup( + request: Request, + response: Response, + ): Promise { + const result = await this.groupService.removeItemFromGroup({ + groupUuid: request.params.groupUuid, + itemUuid: request.body.item_uuid, + originatorUuid: response.locals.user.uuid, + }) + + if (!result) { + return this.errorResponse(400, 'Could not remove item from group') + } + + return this.json({ + item: this.itemProjector.projectFull(result), + }) + } + @httpGet('/removed', TYPES.AuthMiddleware) public async getAllRemovedFromGroupsForCurrentUser( _request: Request, @@ -139,6 +157,31 @@ export class GroupsController extends BaseHttpController { }) } + @httpPost('/:groupUuid/valet-tokens', TYPES.AuthMiddleware) + public async getValetTokenForGroupFile( + request: Request, + response: Response, + ): Promise { + const valetTokenResult = await this.createGroupFileReadValetToken.execute({ + userUuid: response.locals.user.uuid, + groupUuid: request.params.groupUuid, + fileUuid: request.body.file_uuid, + remoteIdentifier: request.body.remote_identifier, + operation: request.body.operation, + unencryptedFileSize: request.body.unencrypted_file_size, + moveOperationType: request.body.move_operation_type, + groupToGroupMoveTargetUuid: request.body.group_to_group_move_target_uuid, + }) + + if (valetTokenResult.success === false) { + return this.errorResponse(400, `Failed to create group valet token: ${valetTokenResult.reason}`) + } + + return this.json({ + valetToken: valetTokenResult.valetToken, + }) + } + private errorResponse(status: number, message?: string, tag?: string) { return this.json( { diff --git a/packages/syncing-server/src/Domain/Group/Factory/GroupFactory.ts b/packages/syncing-server/src/Domain/Group/Factory/GroupFactory.ts index fc16b04ea..8febb935c 100644 --- a/packages/syncing-server/src/Domain/Group/Factory/GroupFactory.ts +++ b/packages/syncing-server/src/Domain/Group/Factory/GroupFactory.ts @@ -11,6 +11,7 @@ export class GroupFactory implements GroupFactoryInterface { newGroup.uuid = dto.groupHash.uuid newGroup.userUuid = dto.userUuid newGroup.specifiedItemsKeyUuid = dto.groupHash.specified_items_key_uuid + newGroup.vaultSystemIdentifier = dto.groupHash.vault_system_identifier newGroup.fileUploadBytesUsed = dto.groupHash.file_upload_bytes_used newGroup.fileUploadBytesLimit = dto.groupHash.file_upload_bytes_limit diff --git a/packages/syncing-server/src/Domain/Group/Factory/GroupHash.ts b/packages/syncing-server/src/Domain/Group/Factory/GroupHash.ts index 865fe10f7..4a9ac2feb 100644 --- a/packages/syncing-server/src/Domain/Group/Factory/GroupHash.ts +++ b/packages/syncing-server/src/Domain/Group/Factory/GroupHash.ts @@ -2,6 +2,7 @@ export type GroupHash = { uuid: string user_uuid: string specified_items_key_uuid: string + vault_system_identifier: string file_upload_bytes_used: number file_upload_bytes_limit: number created_at_timestamp?: number diff --git a/packages/syncing-server/src/Domain/Group/Model/Group.ts b/packages/syncing-server/src/Domain/Group/Model/Group.ts index c8db6de04..a8edd5a9d 100644 --- a/packages/syncing-server/src/Domain/Group/Model/Group.ts +++ b/packages/syncing-server/src/Domain/Group/Model/Group.ts @@ -18,6 +18,12 @@ export class Group { }) declare specifiedItemsKeyUuid: string + @Column({ + name: 'vault_system_identifier', + length: 36, + }) + declare vaultSystemIdentifier: string + @Column({ name: 'file_upload_bytes_used', type: 'bigint', diff --git a/packages/syncing-server/src/Domain/Group/Service/GroupService.ts b/packages/syncing-server/src/Domain/Group/Service/GroupService.ts index 47bd7622a..88c7b5e4c 100644 --- a/packages/syncing-server/src/Domain/Group/Service/GroupService.ts +++ b/packages/syncing-server/src/Domain/Group/Service/GroupService.ts @@ -1,3 +1,4 @@ +import { ItemServiceInterface } from './../../Item/ItemServiceInterface' import { TimerInterface } from '@standardnotes/time' import { Group } from '../Model/Group' import { GroupsRepositoryInterface } from '../Repository/GroupRepositoryInterface' @@ -5,6 +6,8 @@ import { CreateGroupDTO, GroupServiceInterface, UpdateGroupDTO, CreateGroupResul import { GroupFactoryInterface } from '../Factory/GroupFactoryInterface' import { GroupUserServiceInterface } from '../../GroupUser/Service/GroupUserServiceInterface' import { GroupInviteServiceInterface } from '../../GroupInvite/Service/GroupInviteServiceInterface' +import { v4 as uuidv4 } from 'uuid' +import { Item } from '../../Item/Item' export class GroupService implements GroupServiceInterface { constructor( @@ -12,21 +15,18 @@ export class GroupService implements GroupServiceInterface { private groupFactory: GroupFactoryInterface, private groupUserService: GroupUserServiceInterface, private groupInviteService: GroupInviteServiceInterface, + private itemService: ItemServiceInterface, private timer: TimerInterface, ) {} - async createGroup(dto: CreateGroupDTO): Promise { - const existingGroup = await this.groupRepository.findByUuid(dto.groupUuid) - if (existingGroup) { - return null - } - + async createGroup(dto: CreateGroupDTO): Promise { const timestamp = this.timer.getTimestampInMicroseconds() const group = this.groupFactory.create({ userUuid: dto.userUuid, groupHash: { - uuid: dto.groupUuid, + uuid: uuidv4(), user_uuid: dto.userUuid, + vault_system_identifier: dto.vaultSystemIdentifier, specified_items_key_uuid: dto.specifiedItemsKeyUuid, file_upload_bytes_limit: 1_000_000, file_upload_bytes_used: 0, @@ -87,10 +87,12 @@ export class GroupService implements GroupServiceInterface { } await this.groupRepository.remove(group) + await this.groupUserService.deleteAllGroupUsersForGroup({ groupUuid: dto.groupUuid, originatorUuid: dto.originatorUuid, }) + await this.groupInviteService.deleteAllInvitesForGroup({ groupUuid: dto.groupUuid, originatorUuid: dto.originatorUuid, @@ -98,4 +100,46 @@ export class GroupService implements GroupServiceInterface { return true } + + async addItemToGroup(dto: { itemUuid: string; groupUuid: string; originatorUuid: string }): Promise { + const item = await this.itemService.getItem({ itemUuid: dto.itemUuid, userUuid: dto.originatorUuid }) + if (!item) { + return null + } + + const groupUser = await this.groupUserService.getUserForGroup({ + userUuid: dto.originatorUuid, + groupUuid: dto.groupUuid, + }) + + if (!groupUser || groupUser.permissions === 'read') { + return null + } + + item.groupUuid = dto.groupUuid + return this.itemService.saveItem(item) + } + + async removeItemFromGroup(dto: { + itemUuid: string + groupUuid: string + originatorUuid: string + }): Promise { + const item = await this.itemService.getItem({ itemUuid: dto.itemUuid, userUuid: dto.originatorUuid }) + if (!item) { + return null + } + + const groupUser = await this.groupUserService.getUserForGroup({ + userUuid: dto.originatorUuid, + groupUuid: dto.groupUuid, + }) + + if (!groupUser || groupUser.permissions === 'read') { + return null + } + + item.groupUuid = null + return this.itemService.saveItem(item) + } } diff --git a/packages/syncing-server/src/Domain/Group/Service/GroupServiceInterface.ts b/packages/syncing-server/src/Domain/Group/Service/GroupServiceInterface.ts index 884c017eb..f55d2e8e3 100644 --- a/packages/syncing-server/src/Domain/Group/Service/GroupServiceInterface.ts +++ b/packages/syncing-server/src/Domain/Group/Service/GroupServiceInterface.ts @@ -1,10 +1,11 @@ import { GroupUser } from './../../GroupUser/Model/GroupUser' import { Group } from '../Model/Group' +import { Item } from '../../Item/Item' export type CreateGroupDTO = { userUuid: string - groupUuid: string specifiedItemsKeyUuid: string + vaultSystemIdentifier: string } export type CreateGroupResult = { @@ -19,13 +20,13 @@ export type UpdateGroupDTO = { } export interface GroupServiceInterface { - createGroup(dto: CreateGroupDTO): Promise - + createGroup(dto: CreateGroupDTO): Promise updateGroup(dto: UpdateGroupDTO): Promise - deleteGroup(dto: { groupUuid: string; originatorUuid: string }): Promise getGroup(dto: { groupUuid: string }): Promise - getGroups(dto: { userUuid: string; lastSyncTime?: number }): Promise + + addItemToGroup(dto: { itemUuid: string; groupUuid: string; originatorUuid: string }): Promise + removeItemFromGroup(dto: { itemUuid: string; groupUuid: string; originatorUuid: string }): Promise } diff --git a/packages/syncing-server/src/Domain/GroupInvite/Factory/GroupInviteFactory.ts b/packages/syncing-server/src/Domain/GroupInvite/Factory/GroupInviteFactory.ts index 625208681..39fc0d2e6 100644 --- a/packages/syncing-server/src/Domain/GroupInvite/Factory/GroupInviteFactory.ts +++ b/packages/syncing-server/src/Domain/GroupInvite/Factory/GroupInviteFactory.ts @@ -13,7 +13,7 @@ export class GroupInviteFactory implements GroupInviteFactoryInterface { newGroupInvite.groupUuid = dto.group_uuid newGroupInvite.inviterUuid = dto.inviter_uuid newGroupInvite.inviterPublicKey = dto.inviter_public_key - newGroupInvite.encryptedGroupData = dto.encrypted_group_data + newGroupInvite.encryptedVaultKeyContent = dto.encrypted_vault_key_content newGroupInvite.inviteType = dto.invite_type newGroupInvite.permissions = dto.permissions diff --git a/packages/syncing-server/src/Domain/GroupInvite/Factory/GroupInviteHash.ts b/packages/syncing-server/src/Domain/GroupInvite/Factory/GroupInviteHash.ts index ad0c381e2..20bffe0b6 100644 --- a/packages/syncing-server/src/Domain/GroupInvite/Factory/GroupInviteHash.ts +++ b/packages/syncing-server/src/Domain/GroupInvite/Factory/GroupInviteHash.ts @@ -7,7 +7,7 @@ export type GroupInviteHash = { group_uuid: string inviter_uuid: string inviter_public_key: string - encrypted_group_data: string + encrypted_vault_key_content: string invite_type: GroupInviteType permissions: GroupUserPermission created_at_timestamp?: number diff --git a/packages/syncing-server/src/Domain/GroupInvite/Model/GroupInvite.ts b/packages/syncing-server/src/Domain/GroupInvite/Model/GroupInvite.ts index f10262bb4..ecabc4d24 100644 --- a/packages/syncing-server/src/Domain/GroupInvite/Model/GroupInvite.ts +++ b/packages/syncing-server/src/Domain/GroupInvite/Model/GroupInvite.ts @@ -35,9 +35,9 @@ export class GroupInvite { declare inviterPublicKey: string @Column({ - name: 'encrypted_group_data', + name: 'encrypted_vault_key_content', }) - declare encryptedGroupData: string + declare encryptedVaultKeyContent: string @Column({ name: 'permissions', diff --git a/packages/syncing-server/src/Domain/GroupInvite/Service/CreateInviteDTO.ts b/packages/syncing-server/src/Domain/GroupInvite/Service/CreateInviteDTO.ts index 6aada1a34..18ff7af9c 100644 --- a/packages/syncing-server/src/Domain/GroupInvite/Service/CreateInviteDTO.ts +++ b/packages/syncing-server/src/Domain/GroupInvite/Service/CreateInviteDTO.ts @@ -6,7 +6,7 @@ export type CreateInviteDTO = { groupUuid: string userUuid: string inviterPublicKey: string - encryptedGroupData: string + encryptedVaultKeyContent: string inviteType: GroupInviteType permissions: GroupUserPermission } diff --git a/packages/syncing-server/src/Domain/GroupInvite/Service/GroupInviteService.ts b/packages/syncing-server/src/Domain/GroupInvite/Service/GroupInviteService.ts index 4c7c58e5e..416987c9a 100644 --- a/packages/syncing-server/src/Domain/GroupInvite/Service/GroupInviteService.ts +++ b/packages/syncing-server/src/Domain/GroupInvite/Service/GroupInviteService.ts @@ -34,7 +34,7 @@ export class GroupInviteService implements GroupInviteServiceInterface { group_uuid: dto.groupUuid, inviter_uuid: dto.originatorUuid, inviter_public_key: dto.inviterPublicKey, - encrypted_group_data: dto.encryptedGroupData, + encrypted_vault_key_content: dto.encryptedVaultKeyContent, invite_type: dto.inviteType, permissions: dto.permissions, created_at_timestamp: timestamp, @@ -51,7 +51,7 @@ export class GroupInviteService implements GroupInviteServiceInterface { } groupInvite.inviterPublicKey = dto.inviterPublicKey - groupInvite.encryptedGroupData = dto.encryptedGroupData + groupInvite.encryptedVaultKeyContent = dto.encryptedVaultKeyContent if (dto.permissions) { groupInvite.permissions = dto.permissions } diff --git a/packages/syncing-server/src/Domain/GroupInvite/Service/GroupInviteServiceInterface.ts b/packages/syncing-server/src/Domain/GroupInvite/Service/GroupInviteServiceInterface.ts index 1dc4fc6c6..255f056fc 100644 --- a/packages/syncing-server/src/Domain/GroupInvite/Service/GroupInviteServiceInterface.ts +++ b/packages/syncing-server/src/Domain/GroupInvite/Service/GroupInviteServiceInterface.ts @@ -5,22 +5,15 @@ import { UpdateInviteDTO } from './UpdateInviteDTO' export interface GroupInviteServiceInterface { createInvite(dto: CreateInviteDTO): Promise - updateInvite(dto: UpdateInviteDTO): Promise - - getInvitesForUser(dto: GetUserGroupInvitesDTO): Promise - - getInvitesForGroup(dto: { groupUuid: string; originatorUuid: string }): Promise - - getOutboundInvitesForUser(dto: { userUuid: string }): Promise - acceptInvite(dto: { originatorUuid: string; inviteUuid: string }): Promise + getInvitesForUser(dto: GetUserGroupInvitesDTO): Promise + getInvitesForGroup(dto: { groupUuid: string; originatorUuid: string }): Promise + getOutboundInvitesForUser(dto: { userUuid: string }): Promise + declineInvite(dto: { originatorUuid: string; inviteUuid: string }): Promise - deleteInvite(dto: { originatorUuid: string; groupUuid: string; inviteUuid: string }): Promise - deleteAllInvitesForGroup(dto: { originatorUuid: string; groupUuid: string }): Promise - deleteAllInboundInvites(dto: { userUuid: string }): Promise } diff --git a/packages/syncing-server/src/Domain/GroupInvite/Service/UpdateInviteDTO.ts b/packages/syncing-server/src/Domain/GroupInvite/Service/UpdateInviteDTO.ts index 7b723ff3e..f0876c750 100644 --- a/packages/syncing-server/src/Domain/GroupInvite/Service/UpdateInviteDTO.ts +++ b/packages/syncing-server/src/Domain/GroupInvite/Service/UpdateInviteDTO.ts @@ -4,6 +4,6 @@ export type UpdateInviteDTO = { originatorUuid: string inviteUuid: string inviterPublicKey: string - encryptedGroupData: string + encryptedVaultKeyContent: string permissions?: GroupUserPermission } diff --git a/packages/syncing-server/src/Domain/Item/Item.ts b/packages/syncing-server/src/Domain/Item/Item.ts index 4ecd9e882..65e250740 100644 --- a/packages/syncing-server/src/Domain/Item/Item.ts +++ b/packages/syncing-server/src/Domain/Item/Item.ts @@ -13,22 +13,6 @@ export class Item { @PrimaryGeneratedColumn('uuid') declare uuid: string - @Column({ - type: 'varchar', - name: 'group_uuid', - length: 255, - nullable: true, - }) - declare groupUuid: string | null - - @Column({ - type: 'varchar', - name: 'vault_identifier', - length: 255, - nullable: true, - }) - declare vault_identifier: string | null - @Column({ type: 'varchar', name: 'duplicate_of', @@ -90,18 +74,6 @@ export class Item { @Index('index_items_on_user_uuid') declare userUuid: string - @Column({ - name: 'last_edited_by_uuid', - length: 36, - }) - declare lastEditedByUuid: string - - @Column({ - name: 'created_by_uuid', - length: 36, - }) - declare createdByUuid: string - @Column({ type: 'tinyint', precision: 1, @@ -111,6 +83,28 @@ export class Item { @Index('index_items_on_deleted') declare deleted: boolean + @Column({ + type: 'varchar', + name: 'vault_system_identifier', + length: 255, + nullable: true, + }) + declare vaultSystemIdentifier: string | null + + @Column({ + type: 'varchar', + name: 'group_uuid', + length: 255, + nullable: true, + }) + declare groupUuid: string | null + + @Column({ + name: 'last_edited_by_uuid', + length: 36, + }) + declare lastEditedByUuid: string + @Column({ name: 'created_at', type: 'datetime', diff --git a/packages/syncing-server/src/Domain/Item/ItemFactory.ts b/packages/syncing-server/src/Domain/Item/ItemFactory.ts index 98cea5d3b..0a7487ca6 100644 --- a/packages/syncing-server/src/Domain/Item/ItemFactory.ts +++ b/packages/syncing-server/src/Domain/Item/ItemFactory.ts @@ -34,8 +34,8 @@ export class ItemFactory implements ItemFactoryInterface { newItem.contentSize = 0 newItem.createdByUuid = dto.userUuid - if (dto.itemHash.group_uuid) { - newItem.groupUuid = dto.itemHash.group_uuid + if (dto.itemHash.vault_system_identifier) { + newItem.groupUuid = dto.itemHash.vault_system_identifier } else { newItem.userUuid = dto.userUuid } diff --git a/packages/syncing-server/src/Domain/Item/ItemHash.ts b/packages/syncing-server/src/Domain/Item/ItemHash.ts index 7aa71410e..1957b6f82 100644 --- a/packages/syncing-server/src/Domain/Item/ItemHash.ts +++ b/packages/syncing-server/src/Domain/Item/ItemHash.ts @@ -10,7 +10,7 @@ export type ItemHash = { auth_hash?: string enc_item_key?: string items_key_id?: string - group_uuid?: string + vault_system_identifier?: string last_edited_by_uuid?: string | null created_at?: string created_at_timestamp?: number diff --git a/packages/syncing-server/src/Domain/Item/ItemService.ts b/packages/syncing-server/src/Domain/Item/ItemService.ts index cb1e7e5f5..ca93fb88a 100644 --- a/packages/syncing-server/src/Domain/Item/ItemService.ts +++ b/packages/syncing-server/src/Domain/Item/ItemService.ts @@ -21,7 +21,6 @@ import { ProjectorInterface } from '../../Projection/ProjectorInterface' import { ItemProjection } from '../../Projection/ItemProjection' import { GroupUserRepositoryInterface } from '../GroupUser/Repository/GroupUserRepositoryInterface' import { ConflictType } from '../../Tmp/ConflictType' -import { GroupServiceInterface } from '../Group/Service/GroupServiceInterface' export class ItemService implements ItemServiceInterface { private readonly DEFAULT_ITEMS_LIMIT = 150 @@ -40,7 +39,6 @@ export class ItemService implements ItemServiceInterface { private itemProjector: ProjectorInterface, private maxItemsSyncLimit: number, private groupUsersRepository: GroupUserRepositoryInterface, - private groupService: GroupServiceInterface, private logger: Logger, ) {} @@ -99,8 +97,6 @@ export class ItemService implements ItemServiceInterface { const savedItems: Array = [] const conflicts: Array = [] - await this.dynamicallyCreateGroupsBasedOnIncomingItems(dto) - const lastUpdatedTimestamp = this.timer.getTimestampInMicroseconds() for (const itemHash of dto.itemHashes) { @@ -187,30 +183,6 @@ export class ItemService implements ItemServiceInterface { return retrievedItems } - private async dynamicallyCreateGroupsBasedOnIncomingItems(dto: SaveItemsDTO): Promise { - const processedGroupUuids = new Set() - - for (const itemHash of dto.itemHashes) { - if (!itemHash.group_uuid || processedGroupUuids.has(itemHash.group_uuid)) { - continue - } - - processedGroupUuids.add(itemHash.group_uuid) - - const vaultItemsKeyUuid = - itemHash.content_type === ContentType.VaultItemsKey ? itemHash.uuid : itemHash.items_key_id - if (!vaultItemsKeyUuid) { - continue - } - - await this.groupService.createGroup({ - userUuid: dto.userUuid, - groupUuid: itemHash.group_uuid, - specifiedItemsKeyUuid: vaultItemsKeyUuid, - }) - } - } - private calculateSyncToken(lastUpdatedTimestamp: number, savedItems: Array): string { if (savedItems.length) { const sortedItems = savedItems.sort((itemA: Item, itemB: Item) => { @@ -238,12 +210,7 @@ export class ItemService implements ItemServiceInterface { dto.existingItem.updatedWithSession = dto.sessionUuid dto.existingItem.contentSize = 0 dto.existingItem.lastEditedByUuid = dto.userUuid - - if (dto.itemHash.group_uuid) { - dto.existingItem.groupUuid = dto.itemHash.group_uuid - } else { - dto.existingItem.groupUuid = null - } + dto.existingItem.vaultSystemIdentifier = dto.itemHash.vault_system_identifier ?? null if (dto.itemHash.content) { dto.existingItem.content = dto.itemHash.content @@ -360,4 +327,17 @@ export class ItemService implements ItemServiceInterface { throw Error('Sync token is missing version part') } } + + public async saveItem(item: Item): Promise { + const updatedAt = this.timer.getTimestampInMicroseconds() + item.updatedAtTimestamp = updatedAt + item.updatedAt = this.timer.convertMicrosecondsToDate(updatedAt) + + const savedItem = await this.itemRepository.save(item) + return savedItem + } + + public async getItem(dto: { itemUuid: string; userUuid: string }): Promise { + return this.itemRepository.findByUuidAndUserUuid(dto.itemUuid, dto.userUuid) + } } diff --git a/packages/syncing-server/src/Domain/Item/ItemServiceInterface.ts b/packages/syncing-server/src/Domain/Item/ItemServiceInterface.ts index b4c6353a7..0762d0bc9 100644 --- a/packages/syncing-server/src/Domain/Item/ItemServiceInterface.ts +++ b/packages/syncing-server/src/Domain/Item/ItemServiceInterface.ts @@ -9,4 +9,6 @@ export interface ItemServiceInterface { saveItems(dto: SaveItemsDTO): Promise frontLoadKeysItemsToTop(userUuid: string, retrievedItems: Array): Promise> getLastSyncTime(dto: { syncToken?: string | null; cursorToken?: string | null }): number | undefined + getItem(dto: { itemUuid: string; userUuid: string }): Promise + saveItem(item: Item): Promise } diff --git a/packages/syncing-server/src/Domain/Item/SaveRule/GroupFilter.ts b/packages/syncing-server/src/Domain/Item/SaveRule/GroupFilter.ts index 3311021cb..d93b3c974 100644 --- a/packages/syncing-server/src/Domain/Item/SaveRule/GroupFilter.ts +++ b/packages/syncing-server/src/Domain/Item/SaveRule/GroupFilter.ts @@ -7,106 +7,69 @@ import { GroupUserPermission } from '../../GroupUser/Model/GroupUserPermission' import { GroupServiceInterface } from '../../Group/Service/GroupServiceInterface' import { ContentType } from '@standardnotes/common' import { ConflictType } from '../../../Tmp/ConflictType' -import { - GroupSaveOperation, - AddToGroupSaveOperation, - RemoveFromGroupSaveOperation, - MoveToOtherGroupSaveOperation, - SaveToGroupSaveOperation, - CreateToGroupSaveOperation, -} from './GroupSaveOperation' -import { Item } from '../Item' export class GroupFilter implements ItemSaveRuleInterface { constructor(private groupService: GroupServiceInterface, private groupUserService: GroupUserServiceInterface) {} async check(dto: ItemSaveValidationDTO): Promise { - if (!dto.existingItem?.groupUuid && !dto.itemHash.group_uuid) { + if (!dto.existingItem?.groupUuid) { return { passed: true, } } - const operation = this.getSaveOperationType(dto) - return this.getResultForOperation(operation) - } - - private async getResultForOperation(operation: GroupSaveOperation): Promise { - if (operation.type === 'add-to-group') { - return this.handleAddToGroupOperation(operation) - } else if (operation.type === 'remove-from-group') { - return this.handleRemoveFromGroupOperation(operation) - } else if (operation.type === 'move-to-other-group') { - return this.handleMoveToOtherGroupOperation(operation) - } else if (operation.type === 'save-to-group') { - return this.handleSaveToGroupOperation(operation) - } else if (operation.type === 'create-to-group') { - return this.handleCreateToGroupOperation(operation) - } - - throw new Error(`Unsupported group operation: ${operation}`) - } - - private getSaveOperationType(dto: ItemSaveValidationDTO): GroupSaveOperation { - const existingItemGroupUuid = dto.existingItem?.groupUuid - const targetItemGroupUuid = dto.itemHash.group_uuid - - const common = { - incomingItem: dto.itemHash, + const groupUser = await this.groupUserService.getUserForGroup({ userUuid: dto.userUuid, - } + groupUuid: dto.existingItem.groupUuid, + }) - if ( - dto.existingItem && - existingItemGroupUuid && - targetItemGroupUuid && - existingItemGroupUuid !== targetItemGroupUuid - ) { + if (!groupUser) { return { - type: 'move-to-other-group', - groupUuid: existingItemGroupUuid, - targetGroupUuid: targetItemGroupUuid, - existingItem: dto.existingItem, - ...common, + passed: false, + conflict: { + unsavedItem: dto.itemHash, + type: ConflictType.GroupNotMemberError, + }, } } - if (dto.existingItem && existingItemGroupUuid && !targetItemGroupUuid) { + if (groupUser.permissions === 'read') { return { - type: 'remove-from-group', - groupUuid: existingItemGroupUuid, - existingItem: dto.existingItem, - ...common, + passed: false, + conflict: { + unsavedItem: dto.itemHash, + serverItem: dto.existingItem, + type: ConflictType.GroupInsufficientPermissionsError, + }, } } - if (dto.existingItem && !existingItemGroupUuid && targetItemGroupUuid) { + if (!this.isAuthorizedToSaveContentType(dto.itemHash.content_type, groupUser.permissions)) { return { - type: 'add-to-group', - groupUuid: targetItemGroupUuid, - existingItem: dto.existingItem, - ...common, + passed: false, + conflict: { + unsavedItem: dto.itemHash, + serverItem: dto.existingItem, + type: ConflictType.GroupInsufficientPermissionsError, + }, } } - if (dto.existingItem && existingItemGroupUuid && existingItemGroupUuid === targetItemGroupUuid) { + const usesValidKey = await this.incomingItemUsesValidItemsKey(dto.itemHash) + if (!usesValidKey) { return { - type: 'save-to-group', - groupUuid: existingItemGroupUuid, - existingItem: dto.existingItem, - ...common, + passed: false, + conflict: { + unsavedItem: dto.itemHash, + serverItem: dto.existingItem, + type: ConflictType.GroupInvalidItemsKey, + }, } } - if (!dto.existingItem && targetItemGroupUuid) { - return { - type: 'create-to-group', - groupUuid: targetItemGroupUuid, - ...common, - } + return { + passed: true, } - - throw new Error('Invalid save operation') } private isAuthorizedToSaveContentType(contentType: ContentType, permissions: GroupUserPermission): boolean { @@ -117,167 +80,13 @@ export class GroupFilter implements ItemSaveRuleInterface { return true } - private buildFailResult(operation: GroupSaveOperation, type: ConflictType, serverItem?: Item) { - return { - passed: false, - conflict: { - unsavedItem: operation.incomingItem, - serverItem, - type, - }, - } - } - - private buildSuccessValue(): ItemSaveRuleResult { - return { - passed: true, - } - } - - private async handleAddToGroupOperation(operation: AddToGroupSaveOperation): Promise { - const groupPermissions = await this.getGroupPermissions(operation.userUuid, operation.groupUuid) - if (!groupPermissions) { - return this.buildFailResult(operation, ConflictType.GroupNotMemberError) - } - - if (operation.existingItem.deleted || operation.incomingItem.deleted) { - return this.buildFailResult(operation, ConflictType.GroupInvalidState) - } - - if (!this.isAuthorizedToSaveContentType(operation.incomingItem.content_type, groupPermissions)) { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - if (groupPermissions === 'read') { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - if (operation.existingItem.userUuid !== operation.userUuid) { - return this.buildFailResult(operation, ConflictType.UuidConflict) - } - - const usesValidKey = await this.incomingItemUsesValidItemsKey(operation.incomingItem) - if (!usesValidKey) { - return this.buildFailResult(operation, ConflictType.GroupInvalidItemsKey, operation.existingItem) - } - - return this.buildSuccessValue() - } - - private async handleRemoveFromGroupOperation(operation: RemoveFromGroupSaveOperation): Promise { - const groupPermissions = await this.getGroupPermissions(operation.userUuid, operation.groupUuid) - if (!groupPermissions) { - return this.buildFailResult(operation, ConflictType.GroupNotMemberError) - } - - if (operation.existingItem.deleted || operation.incomingItem.deleted) { - return this.buildFailResult(operation, ConflictType.GroupInvalidState) - } - - if (operation.existingItem.userUuid === operation.userUuid) { - return this.buildSuccessValue() - } - - if (!this.isAuthorizedToSaveContentType(operation.incomingItem.content_type, groupPermissions)) { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - if (groupPermissions === 'read') { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - const usesValidKey = await this.incomingItemUsesValidItemsKey(operation.incomingItem) - if (!usesValidKey) { - return this.buildFailResult(operation, ConflictType.GroupInvalidItemsKey, operation.existingItem) - } - - return this.buildSuccessValue() - } - - private async handleMoveToOtherGroupOperation(operation: MoveToOtherGroupSaveOperation): Promise { - const sourceGroupPermissions = await this.getGroupPermissions(operation.userUuid, operation.groupUuid) - const targetGroupPermissions = await this.getGroupPermissions(operation.userUuid, operation.targetGroupUuid) - - if (!sourceGroupPermissions || !targetGroupPermissions) { - return this.buildFailResult(operation, ConflictType.GroupNotMemberError) - } - - if (operation.existingItem.deleted || operation.incomingItem.deleted) { - return this.buildFailResult(operation, ConflictType.GroupInvalidState) - } - - if (sourceGroupPermissions === 'read' || targetGroupPermissions === 'read') { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - if ( - !this.isAuthorizedToSaveContentType(operation.incomingItem.content_type, sourceGroupPermissions) || - !this.isAuthorizedToSaveContentType(operation.incomingItem.content_type, targetGroupPermissions) - ) { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - const usesValidKey = await this.incomingItemUsesValidItemsKey(operation.incomingItem) - if (!usesValidKey) { - return this.buildFailResult(operation, ConflictType.GroupInvalidItemsKey, operation.existingItem) - } - - return this.buildSuccessValue() - } - - private async handleSaveToGroupOperation(operation: SaveToGroupSaveOperation): Promise { - const groupPermissions = await this.getGroupPermissions(operation.userUuid, operation.groupUuid) - - if (!groupPermissions) { - return this.buildFailResult(operation, ConflictType.GroupNotMemberError) - } - - if (!this.isAuthorizedToSaveContentType(operation.incomingItem.content_type, groupPermissions)) { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - if (groupPermissions === 'read') { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - const usesValidKey = await this.incomingItemUsesValidItemsKey(operation.incomingItem) - if (!usesValidKey) { - return this.buildFailResult(operation, ConflictType.GroupInvalidItemsKey, operation.existingItem) - } - - return this.buildSuccessValue() - } - - private async handleCreateToGroupOperation(operation: CreateToGroupSaveOperation): Promise { - const groupPermissions = await this.getGroupPermissions(operation.userUuid, operation.groupUuid) - - if (!groupPermissions) { - return this.buildFailResult(operation, ConflictType.GroupNotMemberError) - } - - if (!this.isAuthorizedToSaveContentType(operation.incomingItem.content_type, groupPermissions)) { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - if (groupPermissions === 'read') { - return this.buildFailResult(operation, ConflictType.GroupInsufficientPermissionsError) - } - - const usesValidKey = await this.incomingItemUsesValidItemsKey(operation.incomingItem) - if (!usesValidKey) { - return this.buildFailResult(operation, ConflictType.GroupInvalidItemsKey) - } - - return this.buildSuccessValue() - } - private async incomingItemUsesValidItemsKey(itemHash: ItemHash): Promise { const isItemNotEncryptedByItemsKey = itemHash.content_type === ContentType.VaultItemsKey if (isItemNotEncryptedByItemsKey) { return true } - const group = await this.groupService.getGroup({ groupUuid: itemHash.group_uuid as string }) + const group = await this.groupService.getGroup({ groupUuid: itemHash.vault_system_identifier as string }) if (!group) { return false @@ -285,17 +94,4 @@ export class GroupFilter implements ItemSaveRuleInterface { return itemHash.items_key_id === group.specifiedItemsKeyUuid } - - private async getGroupPermissions(userUuid: string, groupUuid: string): Promise { - const groupUser = await this.groupUserService.getUserForGroup({ - userUuid, - groupUuid: groupUuid, - }) - - if (groupUser) { - return groupUser.permissions - } - - return undefined - } } diff --git a/packages/syncing-server/src/Domain/Item/SaveRule/GroupSaveOperation.ts b/packages/syncing-server/src/Domain/Item/SaveRule/GroupSaveOperation.ts deleted file mode 100644 index 51307e8df..000000000 --- a/packages/syncing-server/src/Domain/Item/SaveRule/GroupSaveOperation.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ItemHash } from '../ItemHash' -import { Item } from '../Item' - -type SaveOperationCommon = { - incomingItem: ItemHash - userUuid: string -} - -export type AddToGroupSaveOperation = SaveOperationCommon & { - type: 'add-to-group' - groupUuid: string - existingItem: Item -} - -export type RemoveFromGroupSaveOperation = SaveOperationCommon & { - type: 'remove-from-group' - groupUuid: string - existingItem: Item -} - -export type MoveToOtherGroupSaveOperation = SaveOperationCommon & { - type: 'move-to-other-group' - groupUuid: string - targetGroupUuid: string - existingItem: Item -} - -export type SaveToGroupSaveOperation = SaveOperationCommon & { - type: 'save-to-group' - groupUuid: string - existingItem: Item -} - -export type CreateToGroupSaveOperation = SaveOperationCommon & { - type: 'create-to-group' - groupUuid: string -} - -export type GroupSaveOperation = - | AddToGroupSaveOperation - | RemoveFromGroupSaveOperation - | MoveToOtherGroupSaveOperation - | SaveToGroupSaveOperation - | CreateToGroupSaveOperation diff --git a/packages/syncing-server/src/Domain/Item/SaveRule/GroupSnjsVersionFilter.ts b/packages/syncing-server/src/Domain/Item/SaveRule/GroupSnjsVersionFilter.ts index 841865006..e5b25bfb4 100644 --- a/packages/syncing-server/src/Domain/Item/SaveRule/GroupSnjsVersionFilter.ts +++ b/packages/syncing-server/src/Domain/Item/SaveRule/GroupSnjsVersionFilter.ts @@ -12,7 +12,7 @@ export class GroupSnjsVersionFilter implements ItemSaveRuleInterface { passed: true, } - const groupUuidInvolved = dto.existingItem?.groupUuid || dto.itemHash.group_uuid + const groupUuidInvolved = dto.existingItem?.groupUuid || dto.itemHash.vault_system_identifier if (!groupUuidInvolved) { return successValue } diff --git a/packages/syncing-server/src/Domain/Item/SaveRule/OwnershipFilter.ts b/packages/syncing-server/src/Domain/Item/SaveRule/OwnershipFilter.ts index 3a8840ea0..e5de60d06 100644 --- a/packages/syncing-server/src/Domain/Item/SaveRule/OwnershipFilter.ts +++ b/packages/syncing-server/src/Domain/Item/SaveRule/OwnershipFilter.ts @@ -5,7 +5,7 @@ import { ConflictType } from '../../../Tmp/ConflictType' export class OwnershipFilter implements ItemSaveRuleInterface { async check(dto: ItemSaveValidationDTO): Promise { - const deferToGroupFilter = dto.existingItem?.groupUuid || dto.itemHash.group_uuid + const deferToGroupFilter = dto.existingItem?.groupUuid if (deferToGroupFilter) { return { passed: true, diff --git a/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItem.spec.ts b/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItem.spec.ts deleted file mode 100644 index 4c5606fdc..000000000 --- a/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItem.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import 'reflect-metadata' -import { Item } from '../../Item/Item' -import { ItemRepositoryInterface } from '../../Item/ItemRepositoryInterface' - -import { GetGlobalItem } from './GetGlobalItem' - -describe('GetGlobalItem', () => { - let itemRepository: ItemRepositoryInterface - - const createUseCase = () => new GetGlobalItem(itemRepository) - - beforeEach(() => { - itemRepository = {} as jest.Mocked - itemRepository.findByUuid = jest.fn().mockReturnValue(null) - }) - - it('should fail if item is not found', async () => { - expect( - await createUseCase().execute({ - itemUuid: '2-3-4', - }), - ).toEqual({ success: false, message: 'Could not find item with uuid 2-3-4' }) - }) - - it('should succeed if item is found', async () => { - const item = {} as jest.Mocked - itemRepository.findByUuid = jest.fn().mockReturnValue(item) - - expect( - await createUseCase().execute({ - itemUuid: '2-3-4', - }), - ).toEqual({ success: true, item }) - }) -}) diff --git a/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItem.ts b/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItem.ts deleted file mode 100644 index 1fa6f6f2a..000000000 --- a/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItem.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ItemRepositoryInterface } from '../../Item/ItemRepositoryInterface' -import { UseCaseInterface } from '../UseCaseInterface' -import { GetGlobalItemDTO } from './GetGlobalItemDTO' -import { GetGlobalItemResponse } from './GetGlobalItemResponse' - -export class GetGlobalItem implements UseCaseInterface { - constructor(private itemRepository: ItemRepositoryInterface) {} - - async execute(dto: GetGlobalItemDTO): Promise { - const item = await this.itemRepository.findByUuid(dto.itemUuid) - - if (item === null) { - return { - success: false, - message: `Could not find item with uuid ${dto.itemUuid}`, - } - } - - return { - success: true, - item, - } - } -} diff --git a/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItemDTO.ts b/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItemDTO.ts deleted file mode 100644 index 9c69f1905..000000000 --- a/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItemDTO.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type GetGlobalItemDTO = { - itemUuid: string -} diff --git a/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItemResponse.ts b/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItemResponse.ts deleted file mode 100644 index 7e974fed8..000000000 --- a/packages/syncing-server/src/Domain/UseCase/GetGlobalItem/GetGlobalItemResponse.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Item } from '../../Item/Item' - -export type GetGlobalItemResponse = - | { - success: true - item: Item - } - | { - success: false - message: string - } diff --git a/packages/syncing-server/src/Projection/GroupInviteProjection.ts b/packages/syncing-server/src/Projection/GroupInviteProjection.ts index d7260185e..27781456e 100644 --- a/packages/syncing-server/src/Projection/GroupInviteProjection.ts +++ b/packages/syncing-server/src/Projection/GroupInviteProjection.ts @@ -6,7 +6,7 @@ export type GroupInviteProjection = { user_uuid: string inviter_uuid: string inviter_public_key: string - encrypted_group_data: string + encrypted_vault_key_content: string invite_type: GroupInviteType permissions: string created_at_timestamp: number diff --git a/packages/syncing-server/src/Projection/GroupInviteProjector.ts b/packages/syncing-server/src/Projection/GroupInviteProjector.ts index 1d4d4e69d..fdbcf3d45 100644 --- a/packages/syncing-server/src/Projection/GroupInviteProjector.ts +++ b/packages/syncing-server/src/Projection/GroupInviteProjector.ts @@ -23,7 +23,7 @@ export class GroupInviteProjector implements ProjectorInterface